Wrap words that have an asterisk suffix in <u> and </u> tags.
This should underline starred names to show the preferred name.

@param string $textSpan
@param string $direction

@return string
328660
public static function starredName($textSpan, $direction): string
    {
        // To avoid a TCPDF bug that mixes up the word order, insert those <u> and </u> tags
        // only when page and span directions are identical.
        if ($direction === strtoupper(I18N::direction())) {
            while (true) {
                $starPos = strpos($textSpan, '*');
                if ($starPos === false) {
                    break;
                }
                $trailingText = substr($textSpan, $starPos + 1);
                $textSpan     = substr($textSpan, 0, $starPos);
                $wordStart    = strrpos($textSpan, ' '); // Find the start of the word
                if ($wordStart !== false) {
                    $leadingText = substr($textSpan, 0, $wordStart + 1);
                    $wordText    = substr($textSpan, $wordStart + 1);
                } else {
                    $leadingText = '';
                    $wordText    = $textSpan;
                }
                $textSpan = $leadingText . '<u>' . $wordText . '</u>' . $trailingText;
            }
            $textSpan = preg_replace('~<span class="starredname">(.*)</span>~', '<u>\1</u>', $textSpan);
            // The &nbsp; is a work-around for a TCPDF bug eating blanks.
            $textSpan = str_replace([
                ' <u>',
                '</u> ',
            ], [
                '&nbsp;<u>',
                '</u>&nbsp;',
            ], $textSpan);
        } else {
            // Text and page directions differ:  remove the <span> and </span>
            $textSpan = preg_replace('~(.*)\*~', '\1', $textSpan);
            $textSpan = preg_replace('~<span class="starredname">(.*)</span>~', '\1', $textSpan);
        }

        return $textSpan;
    }
592623
public function get($direction = 'regular')
    {
        if ($this->count() == 0) {
            return $this->default;
        }

        if ($direction === 'downward') {
            $this->collection = array_reverse($this->collection);
        }

        $this->addPageName();

        if ($direction === 'reverse') {
            $this->collection = array_reverse($this->collection);
        }

        return implode($this->getDelimeter(), $this->collection);
    }
192334
private function wrapHeadlinesWithEmptyLines(string $content): string
    {
        return Strings::replace($content, self::HEADLINE_PATTERN, function (array $match) {
            return PHP_EOL . $match['headline'] . PHP_EOL;
        });
    }
1017147
public static function sortKeys(array $array, string $direction = 'ASC')
    {
        $direction = (strtolower($direction) === 'desc') ? SORT_DESC : SORT_ASC;
        if ($direction === SORT_ASC) {
            ksort($array);
        } else {
            krsort($array);
        }

        return $array;
    }
563972
private void parseBoldAndItalicSpans(SpanManager sm, Span line,
			List<Span> boldSpans, List<Span> italicSpans)
	{
		// Das suchen nach BOLD und ITALIC muss in den Jeweiligen
		// Zeilen geschenhen, da ein LineSeparator immer BOLD und
		// Italic Tags schliesst.

		// Bold Spans
		parseQuotedSpans(sm, line, boldSpans, "'''");

		// Italic Spans
		parseQuotedSpans(sm, line, italicSpans, "''");

		// Maybe there is ONE SINGLE OPEN TAG left... handel these...
		int openTag = sm.indexOf("''", line);
		if (openTag != -1)
		{
			// build a Span from this Tag.
			Span qs = new Span(openTag, line.getEnd());

			// calculate the original src positions.
			if (calculateSrcSpans)
			{
				qs.setSrcSpan(new SrcSpan(sm.getSrcPos(openTag), sm
						.getSrcPos(line.getEnd())));
			}

			// is it a Bold or an Italic tag ?
			if (sm.indexOf("'''", openTag, openTag + 3) != -1)
			{
				// --> BOLD
				boldSpans.add(qs);
				sm.delete(openTag, openTag + 3);
			}
			else
			{
				// --> ITALIC
				italicSpans.add(qs);
				sm.delete(openTag, openTag + 2);
			}
		}
	}
1077309
public static function swrap($string, $symmetricWrapper) {
    if ($symmetricWrapper === '[') {
      return '['.$string.']';
    } elseif ($symmetricWrapper === '(') {
      return '('.$string.')';
    } else {
      return $symmetricWrapper.$string.$symmetricWrapper;
    }
  }
61442
protected function _getUpdateExpression($direction = '+')
    {
        $field = $this->_config['order'];

        return $this->_table->query()->newExpr()
            ->add(new IdentifierExpression($field))
            ->add('1')
            ->setConjunction($direction);
    }
284037
public function getExclusiveTokenString($direction = self::NEXT, $allowedTokensBetween = array(), $useDefaultIgnores = true)
    {

        $token = $this->getExclusiveToken($direction, $allowedTokensBetween, $useDefaultIgnores);

        if (is_array($token)) {
            if (is_int($token[0]) || $token[0] instanceof Enum) {
                return $token[1];
            } else {
                return (string)$token[0];
            }
        } else {
            return (string)$token;
        }
    }
41446
public static function underdashToCamel($s)
	{
		$s = strtolower($s);
		$s = preg_replace('#_(?=[a-z])#', ' ', $s);
		$s = substr(ucwords('x' . $s), 1);
		$s = str_replace(' ', '', $s);

		return $s;
	}
665362
function getNsIndex( $text ) {
		$lctext = $this->lc( $text );
		if ( ( $ns = MWNamespace::getCanonicalIndex( $lctext ) ) !== null ) {
			return $ns;
		}
		$ids = $this->getNamespaceIds();
		return isset( $ids[$lctext] ) ? $ids[$lctext] : false;
	}
335810
public function nlToPbr($string)
	{
		$string = trim($string);
		$string = Modifiers::linebreaks($string);
		$string = str_replace("\n", '<br />', $string);
		$string = str_replace('<br /><br />', "</p>\n<p>", $string);
		$string = str_replace('<p></p>', '', $string);
		return '<p>' . $string . '</p>' . PHP_EOL;
	}
669963
public static function GetNamespaceUriForPrefix( $context, $prefix, $nav )
	{
		$ns  = "";
		if ( $prefix instanceof  Undefined || $prefix . "" == "" )
		{
			$ns = $nav->getNamespaceURI();
		}
		else
		{
			/**
			 * @var XmlNamespaceManager $nsmgr
			 */
		    $nsmgr = new XmlNamespaceManager();
		    ExtFuncs::ScanLocalNamespaces( $nsmgr, $nav->CloneInstance(), false );
		    $ns = $nsmgr->lookupNamespace( $prefix . "" );
		}
		return is_null( $ns )
			? Undefined::getValue()
			: new AnyUriValue( $ns );
	}
902283
private function salted($key, $suffix = null)
    {
        $delimiter = ':';
        if (defined('static::DELIMITER')) {
            $delimiter = static::DELIMITER;
        }

        if (defined('static::PREFIX')) {
            $key = sprintf('%s%s%s', static::PREFIX, $delimiter, $key);
        }

        if ($suffix) {
            return sprintf('%s%s%s', $key, $delimiter, $suffix);
        }

        return $key;
    }
36077
public function typography($text, array $rules = null)
    {
        if ($rules === null) {
            $rules = TypoRules::$STANDARD_RULES;
        }
        if (array_diff($rules, TypoRules::$EXTENDED_RULES)) {
            throw new \InvalidArgumentException('Invalid typo rules');
        }

        foreach ($rules as $rule) {
            $funcName = 'rl'.$rule;
            $text = call_user_func(array($this, $funcName), $text);
        }
        return $text;
    }
1254031
private function getFirstLastEventPlace(string $direction): string
    {
        $row = $this->eventQuery($direction);

        if ($row) {
            $record = GedcomRecord::getInstance($row->id, $this->tree);
            $fact   = null;

            if ($record) {
                $fact = $record->facts([$row->fact])->first();
            }

            if ($fact instanceof Fact) {
                return FunctionsPrint::formatFactPlace($fact, true, true, true);
            }
        }

        return I18N::translate('Private');
    }
1210048
public function apply( \DOMText $textnode, Settings $settings, $is_title = false ) {
		if ( empty( $settings['frenchPunctuationSpacing'] ) ) {
			return;
		}

		// Use the proper non-breaking narrow space.
		$no_break_narrow_space = $settings->no_break_narrow_space();

		// Need to get context of adjacent characters outside adjacent inline tags or HTML comment
		// if we have adjacent characters add them to the text.
		$previous_character = DOM::get_prev_chr( $textnode );
		$next_character     = DOM::get_next_chr( $textnode );
		$node_data          = "{$previous_character}{$textnode->data}"; // $next_character is not included on purpose.
		$f                  = Strings::functions( "{$node_data}{$next_character}" ); // Include $next_character for determining encodiing.

		$node_data = \preg_replace( self::INSERT_SPACE_BEFORE_CLOSING_QUOTE, '$1' . $no_break_narrow_space . '$3$4', $node_data );
		$node_data = \preg_replace( self::INSERT_NARROW_SPACE,               '$1' . $no_break_narrow_space . '$3$4', $node_data );
		$node_data = \preg_replace( self::INSERT_FULL_SPACE,                 '$1' . U::NO_BREAK_SPACE . '$3$4',      $node_data );

		// The next rule depends on the following characters as well.
		$node_data = \preg_replace( self::INSERT_SPACE_AFTER_OPENING_QUOTE,  '$1$2' . $no_break_narrow_space . '$4', "{$node_data}{$next_character}" );

		// If we have adjacent characters remove them from the text.
		$textnode->data = self::remove_adjacent_characters( $node_data, $f['strlen'], $f['substr'], $f['strlen']( $previous_character ), $f['strlen']( $next_character ) );
	}
635073
public static String getFetchDirectionString(int direction) {
        switch (direction) {
            case ResultSet.FETCH_FORWARD:
                return "FETCH FORWARD (" + direction + ')'; 

            case ResultSet.FETCH_REVERSE:
                return "FETCH REVERSE (" + direction + ')'; 

            case ResultSet.FETCH_UNKNOWN:
                return "FETCH UNKNOWN (" + direction + ')'; 
        }

        return "UNRECOGNIZED FETCH DIRECTION CONSTANT (" + direction + ')'; 
    }