<commit_before><?php

	/**
	 * Text parser class
	 *
	 * @author <NAME> <<EMAIL>>
	 * @version 3.1
	 * @license http://www.opensource.org/licenses/mozilla1.1.php Mozilla Public License 1.1 (MPL 1.1)
	 * @package thebuggenie
	 * @subpackage main
	 */

	/**
	 * Text parser class
	 *
	 * @package thebuggenie
	 * @subpackage main
	 */
	class TBGTextParser
	{

		protected static $additional_regexes = null;
		protected static $current_parser = null;

		protected $preformat = null;
		protected $quote = null;
		protected $tablemode = null;
		protected $opentablecol = false;
		protected $options = array();
		protected $use_toc = false;
		protected $toc_base_id = null;
		protected $openblocks = array();
		protected $nowikis = array();
		protected $elinks = array();
		protected $ilinks = array();
		protected $codeblocks = array();
		protected $linknumber = 0;
		protected $internallinks = array();
		protected $categories = array();
		protected $ignore_newline = false;
		protected $parsed_text = null;
		protected $toc = array();
		protected $text = null;

		/**
		 * Add a regex to be parsed, with a function callback
		 *
		 * @param string $regex
		 * @param callback $callback
		 */
		public static function addRegex($regex, $callback)
		{
			if (self::$additional_regexes === null) self::$additional_regexes = array();
			self::$additional_regexes[] = array($regex, $callback);
		}

		/**
		 * Returns the current parser object, only valid when the _parseText method is running,
		 *
		 * @return TBGTextParser
		 */
		public static function getCurrentParser()
		{
			return self::$current_parser;
		}

		/**
		 * Return an array of the registered regexes to be parsed
		 *
		 * @return array
		 */
		protected static function getRegexes()
		{
			if (self::$additional_regexes === null) self::$additional_regexes = array();
			return self::$additional_regexes;
		}

		/** 
		 * Returns an array of regular expressions that should be used for matching
		 * the issue numbers and workflow transitions in a VCS commit.
		 *
		 * Each element of an array is a single regular expression that will be
		 * applied against the incoming commit message. Each regular expression
		 * should have two named patterns - one denoting the issue number (should
		 * include prefix if used in project), and one denoting workflow
		 * transitions.
		 *
		 * Simple example would be:
		 *
		 * '#fixes issue #(?P<issues>([A-Z0-9]+\-)?\d+) (?P<transitions> \(.*?\))?#i'
		 * 
		 * @return array
		 */
		public static function getIssueRegex()
		{
			// Try getting the regexes from cache first.
			if (!$regex = TBGCache::get(TBGCache::KEY_TEXTPARSER_ISSUE_REGEX))
			{
				// List of keywords that are expected to prefix the issue number in a
				// commit message (these are _not_ project prefixes).
				$issue_strings = array('bug', 'issue', 'ticket', 'fix', 'fixes', 'fixed', 'fixing', 'applies to', 'closes', 'references', 'ref', 'addresses', 're', 'see', 'according to', 'also see', 'story');

				// Add the issue types as prefixes as well.
				foreach (TBGIssuetype::getAll() as $issuetype)
				{
					$issue_strings[] = $issuetype->getName();
				}

				// Construct the OR'ed (|) regex out of issue prefixes.
				$issue_string = join('|', $issue_strings);
				$issue_string = html_entity_decode($issue_string, ENT_QUOTES);
				$issue_string = str_replace(array(' ', "'"), array('\s{1,1}', "\'"), $issue_string);

				// Store all regular expressions for mathces in an array.
				$regex = array();

				// This regex will match messages that contain template like "KEYWORD
				// (#)ISSUE_NUMBER (TRANSITIONS)" (parenthesis means optional). For
				// example:
				// "Resolves issue #2 (Resolve issue)"
				$regex[] = array('#( |^)(?<!\!)(('.$issue_string.')\s\#?(?P<issues>([A-Z0-9]+\-)?\d+))(?P<transitions> \(.*?\))?#i');
				// This regex will match messages that contain template at the beginning
				// of message in format "ISSUE_NUMBER: (TRANSITIONS)".
				$regex[] = array('#^(?<!\!)((?P<issues>([A-Z0-9]+\-)?\d+)):(?P<transitions> \(.*?\))?#i');

				// Add the constructed regexes to cache.
				TBGCache::add(TBGCache::KEY_TEXTPARSER_ISSUE_REGEX, $regex);
			}

			// Return the regular expressions.
			return $regex;
		}

		/**
		 * Setup the parser object
		 *
		 * @param string $text The text to be parsed
		 * @param boolean $use_toc[optional] Whether to use a TOC if found
		 * @param string $toc_base_id[optional] Base id to use for the TOC element
		 */
		public function __construct($text, $use_toc = false, $toc_base_id = null)
		{
			$this->text = str_replace("\r\n", "\n", $text);
			$this->use_toc = $use_toc;
			$this->toc_base_id = $toc_base_id;

			if (TBGContext::isProjectContext())
			{
				$this->namespace = TBGContext::getCurrentProject()->getKey();
			}
			if (!TBGContext::isCLI())
			{
				TBGContext::loadLibrary('ui');
			}
		}<commit_msg>Removed erroneous array wrapper around the issue regular expressions. Fixes #1995.<commit_after><?php

	/**
	 * Text parser class
	 *
	 * @author <NAME> <<EMAIL>>
	 * @version 3.1
	 * @license http://www.opensource.org/licenses/mozilla1.1.php Mozilla Public License 1.1 (MPL 1.1)
	 * @package thebuggenie
	 * @subpackage main
	 */

	/**
	 * Text parser class
	 *
	 * @package thebuggenie
	 * @subpackage main
	 */
	class TBGTextParser
	{

		protected static $additional_regexes = null;
		protected static $current_parser = null;

		protected $preformat = null;
		protected $quote = null;
		protected $tablemode = null;
		protected $opentablecol = false;
		protected $options = array();
		protected $use_toc = false;
		protected $toc_base_id = null;
		protected $openblocks = array();
		protected $nowikis = array();
		protected $elinks = array();
		protected $ilinks = array();
		protected $codeblocks = array();
		protected $linknumber = 0;
		protected $internallinks = array();
		protected $categories = array();
		protected $ignore_newline = false;
		protected $parsed_text = null;
		protected $toc = array();
		protected $text = null;

		/**
		 * Add a regex to be parsed, with a function callback
		 *
		 * @param string $regex
		 * @param callback $callback
		 */
		public static function addRegex($regex, $callback)
		{
			if (self::$additional_regexes === null) self::$additional_regexes = array();
			self::$additional_regexes[] = array($regex, $callback);
		}

		/**
		 * Returns the current parser object, only valid when the _parseText method is running,
		 *
		 * @return TBGTextParser
		 */
		public static function getCurrentParser()
		{
			return self::$current_parser;
		}

		/**
		 * Return an array of the registered regexes to be parsed
		 *
		 * @return array
		 */
		protected static function getRegexes()
		{
			if (self::$additional_regexes === null) self::$additional_regexes = array();
			return self::$additional_regexes;
		}

		/** 
		 * Returns an array of regular expressions that should be used for matching
		 * the issue numbers and workflow transitions in a VCS commit.
		 *
		 * Each element of an array is a single regular expression that will be
		 * applied against the incoming commit message. Each regular expression
		 * should have two named patterns - one denoting the issue number (should
		 * include prefix if used in project), and one denoting workflow
		 * transitions.
		 *
		 * Simple example would be:
		 *
		 * '#fixes issue #(?P<issues>([A-Z0-9]+\-)?\d+) (?P<transitions> \(.*?\))?#i'
		 * 
		 * @return array
		 */
		public static function getIssueRegex()
		{
			// Try getting the regexes from cache first.
			if (!$regex = TBGCache::get(TBGCache::KEY_TEXTPARSER_ISSUE_REGEX))
			{
				// List of keywords that are expected to prefix the issue number in a
				// commit message (these are _not_ project prefixes).
				$issue_strings = array('bug', 'issue', 'ticket', 'fix', 'fixes', 'fixed', 'fixing', 'applies to', 'closes', 'references', 'ref', 'addresses', 're', 'see', 'according to', 'also see', 'story');

				// Add the issue types as prefixes as well.
				foreach (TBGIssuetype::getAll() as $issuetype)
				{
					$issue_strings[] = $issuetype->getName();
				}

				// Construct the OR'ed (|) regex out of issue prefixes.
				$issue_string = join('|', $issue_strings);
				$issue_string = html_entity_decode($issue_string, ENT_QUOTES);
				$issue_string = str_replace(array(' ', "'"), array('\s{1,1}', "\'"), $issue_string);

				// Store all regular expressions for mathces in an array.
				$regex = array();

				// This regex will match messages that contain template like "KEYWORD
				// (#)ISSUE_NUMBER (TRANSITIONS)" (parenthesis means optional). For
				// example:
				// "Resolves issue #2 (Resolve issue)"
				$regex[] = '#( |^)(?<!\!)(('.$issue_string.')\s\#?(?P<issues>([A-Z0-9]+\-)?\d+))(?P<transitions> \(.*?\))?#i';
				// This regex will match messages that contain template at the beginning
				// of message in format "ISSUE_NUMBER: (TRANSITIONS)".
				$regex[] = '#^(?<!\!)((?P<issues>([A-Z0-9]+\-)?\d+)):(?P<transitions> \(.*?\))?#i';

				// Add the constructed regexes to cache.
				TBGCache::add(TBGCache::KEY_TEXTPARSER_ISSUE_REGEX, $regex);
			}

			// Return the regular expressions.
			return $regex;
		}

		/**
		 * Setup the parser object
		 *
		 * @param string $text The text to be parsed
		 * @param boolean $use_toc[optional] Whether to use a TOC if found
		 * @param string $toc_base_id[optional] Base id to use for the TOC element
		 */
		public function __construct($text, $use_toc = false, $toc_base_id = null)
		{
			$this->text = str_replace("\r\n", "\n", $text);
			$this->use_toc = $use_toc;
			$this->toc_base_id = $toc_base_id;

			if (TBGContext::isProjectContext())
			{
				$this->namespace = TBGContext::getCurrentProject()->getKey();
			}
			if (!TBGContext::isCLI())
			{
				TBGContext::loadLibrary('ui');
			}
		}
{'fraction_non_alphanumeric': 0.14825017855320885, 'fraction_numerical': 0.004081216202428324, 'mean_word_length': 3.453430258973194, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '912973', 'n_tokens_mistral': 3606, 'n_tokens_neox': 3023, 'n_words': 925}