Process a font-family listing and return a replacement

@param array $m regex matches

@return string
502734
protected function _fontFamilyCB($m)
    {
        // Issue 210: must not eliminate WS between words in unquoted families
        $flags = PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY;
        $pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], null, $flags);
        $out = 'font-family:';

        while (null !== ($piece = array_shift($pieces))) {
            if ($piece[0] !== '"' && $piece[0] !== "'") {
                $piece = preg_replace('/\\s+/', ' ', $piece);
                $piece = preg_replace('/\\s?,\\s?/', ',', $piece);
            }
            $out .= $piece;
        }

        return $out . $m[2];
    }
127544
protected static function _doShortcode($m)
    {
        // allow {{foo}} syntax for escaping a tag
        if ($m[1] == '{' && $m[6] == '}') {
            return substr($m[0], 1, -1);
        }

        $tag = $m[2];
        $atts = static::_parseAttributes($m[3]);
        $listeners = EventDispatcher::instance('Shortcode')
            ->eventManager()
            ->listeners($tag);

        if (!empty($listeners)) {
            $options = [
                'atts' => (array)$atts,
                'content' => null,
                'tag' => $tag
            ];

            if (isset($m[5])) {
                $options['content'] = $m[5];
            }

            $result = EventDispatcher::instance('Shortcode')
                ->triggerArray([$tag, static::cache('context')], $options)
                ->result;

            return $m[1] . $result . $m[6];
        }

        return '';
    }
378586
protected function selfMaybeCompressCssColorCb(array $m)
    {
        $m['hex'] = strtoupper($m['hex']); // Convert to uppercase for easy comparison.

        if ($m['hex'][0] === $m['hex'][1] && $m['hex'][2] === $m['hex'][3] && $m['hex'][4] === $m['hex'][5]) {
            return $m['context'].$m['hex'][0].$m['hex'][2].$m['hex'][4];
        }
        return $m[0];
    }
354782
protected function _parseAssetCallback($m) {
        if (Config::config()['user']['output']['asset']['enabled']) {
            $data = ['type' => $m[1], 'cache' => $m[3], 'files' => explode(',', $m[2])];

            $asset = new Asset($data);

            if ($m[1] == 'css') {
                return '<link href="{{url:.Gcs.gcs.asset.default:\'' . $asset->getId() . '\',\'' . $asset->getType() . '\'}}" rel="stylesheet" media="screen" type="text/css" />';
            }
            else if ($m[1] == 'js') {
                return '<script type="text/javascript" defer src="{{url:.Gcs.gcs.asset.default:\'' . $asset->getId() . '\',\'' . $asset->getType() . '\'}}" ></script>';
            }
        }
        else {
            $content = '';
            $files = explode(',', $m[2]);

            foreach ($files as $value) {
                $value = preg_replace('#\\n#isU', '', $value);
                $value = preg_replace('#\\r#isU', '', $value);
                $value = preg_replace('#\\t#isU', '', $value);

                if ($m[1] == 'css') {
                    $content .= '<link href="/' . trim($value) . '" rel="stylesheet" media="screen" type="text/css" />' . "\n";
                }
                else {
                    $content .= '<script type="text/javascript" defer src="/' . trim($value) . '"></script>' . "\n";
                }
            }

            return $content;
        }

        return '';
    }
827753
protected function doShortcodeTag($m)
    {
        // allow [[foo]] syntax for escaping a tag
        if ($m[1] == '[' && $m[6] == ']') {
            return substr($m[0], 1, -1);
        }

        $tag = $m[2];
        $attr = $this->parseAttributes($m[3]);

        $callback = $this->_shortcodes[$tag]['callback'];
        $config = $this->_shortcodes[$tag]['config'];

        $attr = ArrayHelper::merge($config, $attr);
        $content = isset($m[5]) ? $m[5] : null;

        $attr['content'] = $content;
        $this->addToPool($tag);
        return $m[1] . call_user_func($callback, $attr, $content, $tag) . $m[6];
    }
272432
function groupTextsByFontFamilyProps(
  textByPropsArray,
  availableFontFaceDeclarations
) {
  const snappedTexts = _.flatMapDeep(textByPropsArray, textAndProps => {
    const family = textAndProps.props['font-family'];
    if (family === undefined) {
      return [];
    }

    // Find all the families in the traced font-family that we have @font-face declarations for:
    const families = fontFamily
      .parse(family)
      .filter(family =>
        availableFontFaceDeclarations.some(
          fontFace =>
            fontFace['font-family'].toLowerCase() === family.toLowerCase()
        )
      );

    return families.map(family => {
      const activeFontFaceDeclaration = fontSnapper(
        availableFontFaceDeclarations,
        {
          ...textAndProps.props,
          'font-family': fontFamily.stringify([family])
        }
      );

      if (!activeFontFaceDeclaration) {
        return [];
      }

      const { relations, ...props } = activeFontFaceDeclaration;
      const fontUrl = getPreferredFontUrl(relations);

      return {
        text: textAndProps.text,
        props,
        fontRelations: relations,
        fontUrl
      };
    });
  }).filter(textByProps => textByProps && textByProps.fontUrl);

  const textsByFontUrl = _.groupBy(snappedTexts, 'fontUrl');

  return _.map(textsByFontUrl, (textsPropsArray, fontUrl) => {
    const texts = textsPropsArray.map(obj => obj.text);
    const fontFamilies = new Set(
      textsPropsArray.map(obj => obj.props['font-family'])
    );
    const pageText = _.uniq(texts.join(''))
      .sort()
      .join('');

    let smallestOriginalSize;
    let smallestOriginalFormat;
    for (const relation of textsPropsArray[0].fontRelations) {
      if (relation.to.isLoaded) {
        const size = relation.to.rawSrc.length;
        if (smallestOriginalSize === undefined || size < smallestOriginalSize) {
          smallestOriginalSize = size;
          smallestOriginalFormat = relation.to.type.toLowerCase();
        }
      }
    }

    return {
      smallestOriginalSize,
      smallestOriginalFormat,
      texts,
      pageText,
      text: pageText,
      props: { ...textsPropsArray[0].props },
      fontUrl,
      fontFamilies
    };
  });
}
15717
function get_font_size()
    {

        if ($this->__font_size_calculated) {
            return $this->_props["font_size"];
        }

        if (!isset($this->_props["font_size"])) {
            $fs = self::$_defaults["font_size"];
        } else {
            $fs = $this->_props["font_size"];
        }

        if (!isset($this->_parent_font_size)) {
            $this->_parent_font_size = self::$default_font_size;
        }

        switch ((string)$fs) {
            case "xx-small":
            case "x-small":
            case "small":
            case "medium":
            case "large":
            case "x-large":
            case "xx-large":
                $fs = self::$default_font_size * self::$font_size_keywords[$fs];
                break;

            case "smaller":
                $fs = 8 / 9 * $this->_parent_font_size;
                break;

            case "larger":
                $fs = 6 / 5 * $this->_parent_font_size;
                break;

            default:
                break;
        }

        // Ensure relative sizes resolve to something
        if (($i = mb_strpos($fs, "em")) !== false) {
            $fs = (float)mb_substr($fs, 0, $i) * $this->_parent_font_size;
        } else if (($i = mb_strpos($fs, "ex")) !== false) {
            $fs = (float)mb_substr($fs, 0, $i) * $this->_parent_font_size;
        } else {
            $fs = (float)$this->length_in_pt($fs);
        }

        //see __set and __get, on all assignments clear cache!
        $this->_prop_cache["font_size"] = null;
        $this->_props["font_size"] = $fs;
        $this->__font_size_calculated = true;
        return $this->_props["font_size"];

    }
342296
protected function convert(
        /*# string */ $name,
        /*# string */ $pattern
    )/*# : string */ {
        $ph = sprintf("\{%s(?:%s)?\}", self::MATCH_GROUP_NAME, self::MATCH_GROUP_TYPE);
        $result = preg_replace([
            '~' . $ph . '(*SKIP)(*FAIL) | \[~x', '~' . $ph . '(*SKIP)(*FAIL) | \]~x',
            '~\{' . self::MATCH_GROUP_NAME . '\}~x', '~' . $ph . '~x',
        ], [
            '(?:', ')?', '{\\1:' . self::MATCH_SEGMENT . '}', '(?<${1}'. $name . '>${2})'
        ], strtr('/' . trim($pattern, '/'), $this->shortcuts));
        return empty($name) ? $result : ("(?<$name>" . $result . ")");
    }
564292
public function merge_font($input_css) {
		$font_prop_default = & $this->parser->data['csstidy']['font_prop_default'];
		$new_font_value = '';
		$important = '';
		// Skip if not font-family and font-size set
		if (isset($input_css['font-family']) && isset($input_css['font-size']) && $input_css['font-family'] != 'inherit') {
			// fix several words in font-family - add quotes
			if (isset($input_css['font-family'])) {
				$families = explode(',', $input_css['font-family']);
				$result_families = array();
				foreach ($families as $family) {
					$family = trim($family);
					$len = strlen($family);
					if (strpos($family, ' ') &&
									!(($family{0} === '"' && $family{$len - 1} === '"') ||
									($family{0} === "'" && $family{$len - 1} === "'"))) {
						$family = '"' . $family . '"';
					}
					$result_families[] = $family;
				}
				$input_css['font-family'] = implode(',', $result_families);
			}
			foreach ($font_prop_default as $font_property => $default_value) {

				// Skip if property does not exist
				if (!isset($input_css[$font_property])) {
					continue;
				}

				$cur_value = $input_css[$font_property];

				// Skip if default value is used
				if ($cur_value === $default_value) {
					continue;
				}

				// Remove !important
				if ($this->parser->is_important($cur_value)) {
					$important = '!important';
					$cur_value = $this->parser->gvw_important($cur_value);
				}

				$new_font_value .= $cur_value;
				// Add delimiter
				$new_font_value .= ( $font_property === 'font-size' &&
								isset($input_css['line-height'])) ? '/' : ' ';
			}

			$new_font_value = trim($new_font_value);

			// Delete all font-properties
			foreach ($font_prop_default as $font_property => $default_value) {
				if ($font_property !== 'font' || !$new_font_value)
					unset($input_css[$font_property]);
			}

			// Add new font property
			if ($new_font_value !== '') {
				$input_css['font'] = $new_font_value . $important;
			}
		}

		return $input_css;
	}
425838
protected function process_value() {
		$google_fonts_array = Fonts::get_google_fonts();
		$backup_fonts       = Fonts::get_backup_fonts();

		$family = $this->value;
		$backup = '';
		if ( is_array( $this->value ) && isset( $this->value[0] ) && isset( $this->value[1] ) ) {
			$family = $this->value[0];
			$backup = $this->value[1];
		}

		// Make sure the value is a string.
		// If not, then early exit.
		if ( ! is_string( $family ) ) {
			return;
		}

		// Hack for standard fonts.
		$family = str_replace( '&quot;', '"', $family );

		// Add backup font.
		if ( Fonts::is_google_font( $family ) ) {

			if ( '' === $backup && isset( $google_fonts_array[ $family ] ) && isset( $backup_fonts[ $google_fonts_array[ $family ]['category'] ] ) ) {
				$backup = $backup_fonts[ $google_fonts_array[ $family ]['category'] ];
			}

			// Add double quotes if needed.
			if ( false !== strpos( $family, ' ' ) && false === strpos( $family, '"' ) ) {
				$this->value = '"' . $family . '", ' . $backup;
				return;
			}
			$this->value = $family . ', ' . $backup;
			return;
		}

		// Add double quotes if needed.
		if ( false !== strpos( $family, ' ' ) && false === strpos( $family, '"' ) ) {
			$this->value = '"' . $family . '"';
		}
		$this->value = html_entity_decode( $family, ENT_QUOTES );
	}
410573
def fontFamilyIndex(qFont, families):
    
    try:
        return families.index(qFont.family())
    except ValueError:
        if False and DEBUGGING:
            raise
        else:
            logger.warn("{} not found in font families, using default.".format(qFont.family()))
            return families.index(qFont.defaultFamily())
944032
public static function get_font_choices() {
		$fonts       = self::get_all_fonts();
		$fonts_array = [];
		foreach ( $fonts as $key => $args ) {
			$fonts_array[ $key ] = $key;
		}
		return $fonts_array;
	}
836460
protected function _parseLangCallBackNoEcho($m) {
        $a = explode(':', $m[2]); //we separate the two sections

        if ($m[1] == ':') {
            $type = '';
        }
        else {
            $type = ', \Gcs\Framework\Core\Lang\Lang::USE_TPL';
        }

        if (isset($a[1])) {
            if (!preg_match('#\$#', $a[0])) {
                return '$this->useLang(\'' . trim($a[0]) . '\',array(' . trim($a[1]) . ')' . $type . ')';
            }
            else {
                return '$this->useLang(' . trim($a[0]) . ',array(' . trim($a[1]) . ')' . $type . ')';
            }
        }
        else {
            if (!preg_match('#\$#', $a[0])) {
                return '$this->useLang(\'' . trim($a[0]) . '\',array()' . $type . ')';
            }
            else {
                return '$this->useLang(' . trim($a[0]) . ',array()' . $type . ')';
            }
        }
    }
1291090
private function _parse_font_face($str)
    {
        $descriptors = $this->_parse_properties($str);

        preg_match_all("/(url|local)\s*\([\"\']?([^\"\'\)]+)[\"\']?\)\s*(format\s*\([\"\']?([^\"\'\)]+)[\"\']?\))?/i", $descriptors->src, $src);

        $sources = array();
        $valid_sources = array();

        foreach ($src[0] as $i => $value) {
            $source = array(
                "local" => strtolower($src[1][$i]) === "local",
                "uri" => $src[2][$i],
                "format" => strtolower($src[4][$i]),
                "path" => Helpers::build_url($this->_protocol, $this->_base_host, $this->_base_path, $src[2][$i]),
            );

            if (!$source["local"] && in_array($source["format"], array("", "truetype"))) {
                $valid_sources[] = $source;
            }

            $sources[] = $source;
        }

        // No valid sources
        if (empty($valid_sources)) {
            return;
        }

        $style = array(
            "family" => $descriptors->get_font_family_raw(),
            "weight" => $descriptors->font_weight,
            "style" => $descriptors->font_style,
        );

        $this->getFontMetrics()->registerFont($style, $valid_sources[0]["path"], $this->_dompdf->getHttpContext());
    }
489947
protected function replace_emoticons($text) {
        global $CFG, $OUTPUT, $PAGE;

        $lang = current_language();
        $theme = $PAGE->theme->name;

        if (!isset(self::$emoticontexts[$lang][$theme]) or !isset(self::$emoticonimgs[$lang][$theme])) {
            // prepare internal caches
            $manager = get_emoticon_manager();
            $emoticons = $manager->get_emoticons();
            self::$emoticontexts[$lang][$theme] = array();
            self::$emoticonimgs[$lang][$theme] = array();
            foreach ($emoticons as $emoticon) {
                self::$emoticontexts[$lang][$theme][] = $emoticon->text;
                self::$emoticonimgs[$lang][$theme][] = $OUTPUT->render($manager->prepare_renderable_emoticon($emoticon));
            }
            unset($emoticons);
        }

        if (empty(self::$emoticontexts[$lang][$theme])) { // No emoticons defined, nothing to process here.
            return $text;
        }

        // Detect all zones that we should not handle (including the nested tags).
        $processing = preg_split('/(<\/?(?:span|script)[^>]*>)/is', $text, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

        // Initialize the results.
        $resulthtml = "";
        $exclude = 0;

        // Define the patterns that mark the start of the forbidden zones.
        $excludepattern = array('/^<script/is', '/^<span[^>]+class="nolink[^"]*"/is');

        // Loop through the fragments.
        foreach ($processing as $fragment) {
            // If we are not ignoring, we MUST test if we should.
            if ($exclude == 0) {
                foreach ($excludepattern as $exp) {
                    if (preg_match($exp, $fragment)) {
                        $exclude = $exclude + 1;
                        break;
                    }
                }
            }
            if ($exclude > 0) {
                // If we are ignoring the fragment, then we must check if we may have reached the end of the zone.
                if (strpos($fragment, '</span') !== false || strpos($fragment, '</script') !== false) {
                    $exclude -= 1;
                    // This is needed because of a double increment at the first element.
                    if ($exclude == 1) {
                        $exclude -= 1;
                    }
                } else if (strpos($fragment, '<span') !== false || strpos($fragment, '<script') !== false) {
                    // If we find a nested tag we increase the exclusion level.
                    $exclude = $exclude + 1;
                }
            } else if (strpos($fragment, '<span') === false ||
                       strpos($fragment, '</span') === false) {
                // This is the meat of the code - this is run every time.
                // This code only runs for fragments that are not ignored (including the tags themselves).
                $fragment = str_replace(self::$emoticontexts[$lang][$theme], self::$emoticonimgs[$lang][$theme], $fragment);
            }
            $resulthtml .= $fragment;
        }

        return $resulthtml;
    }
192389
public function process_fonts() {

		// Early exit if font-family is empty.
		if ( empty( $this->fonts ) ) {
			return;
		}

		foreach ( $this->fonts as $font => $variants ) {

			// Determine if this is indeed a google font or not.
			// If it's not, then just remove it from the array.
			if ( ! array_key_exists( $font, $this->google_fonts ) ) {
				unset( $this->fonts[ $font ] );
				continue;
			}

			// Get all valid font variants for this font.
			$font_variants = [];
			if ( isset( $this->google_fonts[ $font ]['variants'] ) ) {
				$font_variants = $this->google_fonts[ $font ]['variants'];
			}
			foreach ( $variants as $variant ) {

				// If this is not a valid variant for this font-family
				// then unset it and move on to the next one.
				if ( ! in_array( strval( $variant ), $font_variants, true ) ) {
					$variant_key = array_search( $variant, $this->fonts[ $font ], true );
					unset( $this->fonts[ $font ][ $variant_key ] );
					continue;
				}
			}
		}
	}
1115148
private static function updateMac($string)
    {
        $string = mb_ereg_replace_callback('\b(Ma?c)([A-Za-z]+)', function ($matches) {
            return $matches[1] . mb_strtoupper(mb_substr($matches[2], 0, 1)) . mb_substr($matches[2], 1);
        }, $string);

        // Now fix "Mac" exceptions
        foreach (self::$exceptions as $pattern => $replacement) {
            $string = mb_ereg_replace($pattern, $replacement, $string);
        }

        return $string;
    }