function apply_markup($content)
 {
     //Single items only
     if (!is_singular() || !in_the_loop()) {
         return $content;
     }
     //Get the current type
     $type = $this->get_postmeta('rich_snippet_type');
     if (!strlen($type) || $type == 'none') {
         return $content;
     }
     //Get the current format
     $format = 'so';
     //Get tag templates for the current format
     $formats = $this->get_supported_snippet_formats();
     //Get data for the current type
     $types = $this->get_supported_snippet_types();
     $type_data = $types[$type];
     //Cycle through the current type's properties
     $append = '';
     $num_properties = 0;
     $supervalue_regex = '';
     foreach ($type_data['properties'] as $property => $property_data) {
         //Get the property tags
         $tag = is_array($property_data['tags']) ? $property_data['tags'][$format] : $property_data['tags'];
         if (isset($property_data['hidden_tags'])) {
             $hidden_tag = is_array($property_data['hidden_tags']) ? $property_data['hidden_tags'][$format] : $property_data['hidden_tags'];
         } else {
             $hidden_tag = $tag;
         }
         if (isset($property_data['properties']) && is_array($property_data['properties']) && count($property_data['properties'])) {
             $subproperty_regex_pieces = array();
             $subproperty_hidden_markedup_values = array();
             foreach ($property_data['properties'] as $subproperty => $subproperty_data) {
                 //Get the subproperty tags
                 $subproperty_tag = is_array($subproperty_data['tags']) ? $subproperty_data['tags'][$format] : $subproperty_data['tags'];
                 if (isset($subproperty_data['hidden_tags'])) {
                     $subproperty_hidden_tag = is_array($subproperty_data['hidden_tags']) ? $subproperty_data['hidden_tags'][$format] : $subproperty_data['hidden_tags'];
                 } else {
                     $subproperty_hidden_tag = $subproperty_tag;
                 }
                 $subproperty_value = strval($this->get_postmeta("rich_snippet_{$type}_{$property}_{$subproperty}"));
                 if ($subproperty_value) {
                     $subproperty_hidden_markedup_values[] = $this->add_tags($subproperty_value, $subproperty_hidden_tag, $formats[$format]['hidden_property_tags_template']);
                     $subproperty_regex_pieces[] = sustr::preg_escape($subproperty_value);
                 }
             }
             /*$supervalue_regex = implode('(<br ?/?>|\s|,)*?', $subproperty_regex_pieces);*/
             $supervalue_regex = implode('|', $subproperty_regex_pieces);
             $supervalue_regex = "({$supervalue_regex})";
             $supervalue_regex = array_fill(0, count($subproperty_regex_pieces), $supervalue_regex);
             $supervalue_regex = implode('(<br ?/?>|\\s|.){0,20}', $supervalue_regex);
             $this->apply_subproperty_markup_args = array('format' => $format, 'type' => $type, 'property' => $property, 'property_tag' => $tag, 'property_tag_template' => $formats[$format]['property_tags_template'], 'subproperties' => $property_data['properties']);
             $count = 0;
             $content = preg_replace_callback("%({$supervalue_regex})%", array(&$this, 'apply_subproperty_markup'), $content, 1, $count);
             if ($count == 0) {
                 if (count($subproperty_hidden_markedup_values)) {
                     $append .= $this->add_tags(implode($subproperty_hidden_markedup_values), $tag, $formats[$format]['property_tags_template'], false);
                     $num_properties++;
                 }
             } else {
                 $num_properties++;
             }
         } else {
             //Get the current value for this property
             $value = strval($this->get_postmeta("rich_snippet_{$type}_{$property}"));
             if (strlen($value)) {
                 if (sustr::startswith($value, 'obj_') && isset($property_data['jlsuggest']) && $property_data['jlsuggest']) {
                     $value = $this->jlsuggest_value_to_url($value, true);
                 }
             } else {
                 //If a value is not set, look for a value-generating function
                 if (isset($property_data['value_function'])) {
                     $valfunc = (array) $property_data['value_function'];
                     if (is_callable($valfunc[0])) {
                         $valfunc_args = isset($valfunc[1]) ? (array) $valfunc[1] : array();
                         $value = call_user_func_array($valfunc[0], $valfunc_args);
                     }
                 }
             }
             //If still no value, skip this property
             if (!strlen($value)) {
                 continue;
             }
             //Add property tags to the value
             $markedup_value = $this->add_tags($value, $tag, $formats[$format]['property_tags_template']);
             $hidden_markedup_value = $this->add_tags($value, $hidden_tag, $formats[$format]['hidden_property_tags_template']);
             //Apply a value format to visible values if provided
             if (isset($property_data['value_format'])) {
                 $values = array_values(sustr::batch_replace('%s', $value, $property_data['value_format']));
                 $markedup_values = array_values(sustr::batch_replace('%s', $markedup_value, $property_data['value_format']));
             } else {
                 $values = array($value);
                 $markedup_values = array($markedup_value);
             }
             //Is the value in the content, and are we allowed to search/replace the content for this value?
             $count = 0;
             if (empty($property_data['always_hidden'])) {
                 for ($i = 0; $i < count($values); $i++) {
                     $content = sustr::htmlsafe_str_replace($values[$i], $markedup_values[$i], $content, 1, $count);
                     if ($count > 0) {
                         break;
                     }
                 }
             }
             if ($count == 0) {
                 $append .= $hidden_markedup_value;
             }
             $num_properties++;
         }
     }
     if (isset($type_data['content_tags'])) {
         $content_tag = is_array($type_data['content_tags']) ? $type_data['content_tags'][$format] : $type_data['content_tags'];
         $content = $this->add_tags($content, $content_tag, $formats[$format]['property_tags_template'], false);
     }
     if ($num_properties) {
         $type_tag = is_array($type_data['tags']) ? $type_data['tags'][$format] : $type_data['tags'];
         $content = $this->add_tags("{$content}<div>{$append}</div>", $type_tag, $formats[$format]['item_tags_template'], false);
         if ($this->get_setting('mark_code', true, 'settings')) {
             $content .= "\n\n<!-- " . sprintf(__('Schema.org markup generated by %1$s (%2$s)', 'seo-ultimate'), SU_PLUGIN_NAME, SU_PLUGIN_URI) . " -->\n\n";
         }
     }
     //Return filtered content
     return $content;
 }