/** * Rewrite markuped XHTML back to plain Text. AJAX callback * * @author Andreas Gohr <*****@*****.**> */ function spell_resume() { $text = $_POST['data']; //some browsers insert newlines instead of spaces $text = preg_replace("/(\r\n|\n|\r)/", ' ', $text); $text = preg_replace("=<br */?>=i", "\n", $text); // remove HTML tags $text = strip_tags($text); // restore spaces $text = preg_replace('/ /', ' ', $text); $text = preg_replace('/\\xC2\\xA0/', ' ', $text); // restore quoted special chars $text = unhtmlspecialchars($text); // check if UTF-8 is accepted if (!$_POST['utf8']) { // protect '&' (gets removed in JS later) $text = str_replace('&', '&', $text); // encode multibyte chars as entities for broken Konqueror $text = utf8_tohtml($text); } // output print $text; }
function test_from_4byte() { $in = ""; $out = '􀀁'; $this->assertEqual(utf8_tohtml($in), $out); }
/** * Parses a projection group in 'long syntax'. */ function parseFieldsLong($lines, &$typemap) { $p = $this->getPatterns(); $result = array(); foreach ($lines as $lineNode) { $line = trim($lineNode['text']); // FIELDLONG := VARIABLE AGGREGATE? TYPE? (':' ANY)? if (preg_match("/^({$p->variable})\\s*({$p->aggregate})?\\s*({$p->type})?(?:\\s*(:)\\s*({$p->any})?\\s*)?\$/S", $line, $match)) { list(, $var, $vaggregate, $vtype, $nocaphint, $caption) = $match; $variable = $p->variable($var)->name; if (!$nocaphint || !$nocaphint && !$caption) { $caption = ucfirst($variable); } list($type, $hint) = $p->type($vtype); list($agg, $agghint) = $p->aggregate($vaggregate); $this->updateTypemap($typemap, $variable, $type, $hint); $result[] = array('variable' => $variable, 'caption' => $caption, 'aggregate' => $agg, 'aggregateHint' => $agghint, 'type' => $type, 'hint' => $hint); } else { $this->_fail(sprintf($this->getLang('error_query_fieldsline'), utf8_tohtml(hsc($line))), $lineNode); } } return $result; }
function handle($match, $state, $pos, &$handler) { $result = array('entry' => '', 'data' => array($this->util->getIsaKey(false) => array(), $this->util->getTitleKey(false) => array())); // allow for preprocessing by a subclass $match = $this->preprocess($match, $state, $pos, $handler, $result); $lines = explode("\n", $match); $header = trim(array_shift($lines)); $footer = trim(array_pop($lines)); // allow subclasses to mangle header $header = $this->handleHeader($header, $result); // extract header, and match it to get classes and fragment preg_match('/^( +[^#>]+)?(?: *#([^>]*?))?$/', $header, $header); // process the classes into triples foreach (preg_split('/\\s+/', trim($header[1])) as $class) { if ($class == '') { continue; } $result['data'][$this->util->getIsaKey(false)][] = array('value' => $class, 'type' => 'text', 'hint' => null); } // process the fragment if necessary $result['entry'] = $header[2]; $result['position'] = $pos; if ($result['entry'] != '') { $result['title candidate'] = array('value' => $result['entry'], 'type' => 'text', 'hint' => null); } // parse tree $tree = $this->syntax->constructTree($lines, 'data entry'); // allow subclasses first pick in the tree $this->handleBody($tree, $result); // fetch all lines $lines = $this->syntax->extractText($tree); // sanity check if (count($tree['cs'])) { msg(sprintf($this->syntax->getLang('error_entry_block'), $tree['cs'][0]['tag'] ? sprintf($this->syntax->getLang('named_group'), utf8_tohtml(hsc($tree['cs'][0]['tag']))) : $this->syntax->getLang('unnamed_group'), utf8_tohtml(hsc($result['entry']))), -1); return array(); } $p = $this->syntax->getPatterns(); // now handle all lines foreach ($lines as $line) { $line = $line['text']; // match a "property_type(hint)*: value" pattern // (the * is only used to indicate that the value is actually a comma-seperated list) // [grammar] ENTRY := PREDICATE TYPE? '*'? ':' ANY if (preg_match("/^({$p->predicate})\\s*({$p->type})?\\s*(\\*)?\\s*:\\s*({$p->any}?)\$/", $line, $parts)) { // assign useful names list(, $property, $ptype, $multi, $values) = $parts; list($type, $hint) = $p->type($ptype); // trim property so we don't get accidental 'name ' keys $property = utf8_trim($property); // lazy create key bucket if (!isset($result['data'][$property])) { $result['data'][$property] = array(); } // determine values, splitting on commas if necessary $values = $multi == '*' ? explode(',', $values) : array($values); // generate triples from the values foreach ($values as $v) { $v = utf8_trim($v); if ($v == '') { continue; } // replace the [[]] quasi-magic token with the empty string if ($v == '[[]]') { $v = ''; } if (!isset($type) || $type == '') { list($type, $hint) = $this->util->getDefaultType(); } $result['data'][$property][] = array('value' => $v, 'type' => $type, 'hint' => $hint ?: null); } } else { msg(sprintf($this->syntax->getLang('error_entry_line'), utf8_tohtml(hsc($line))), -1); } } // normalize data: // - Normalize all values $buckets = $result['data']; $result['data'] = array(); foreach ($buckets as $property => &$bucket) { // normalize the predicate $property = $this->util->normalizePredicate($property); // process all triples foreach ($bucket as &$triple) { // normalize the value $type = $this->util->loadType($triple['type']); $triple['value'] = $type->normalize($triple['value'], $triple['hint']); // lazy create property bucket if (!isset($result['data'][$property])) { $result['data'][$property] = array(); } $result['data'][$property][] = $triple; } } // normalize title candidate if (!empty($result['title candidate'])) { $type = $this->util->loadType($result['title candidate']['type']); $result['title candidate']['value'] = $type->normalize($result['title candidate']['value'], $result['title candidate']['hint']); } $footer = $this->handleFooter($footer, $result); return $result; }
function handle($match, $state, $pos, &$handler) { try { $result = array(); $typemap = array(); // allow subclass handling of the whole match $match = $this->preprocess($match, $state, $pos, $handler, $result, $typemap); // split into lines and remove header and footer $lines = explode("\n", $match); $header = trim(array_shift($lines)); $footer = trim(array_pop($lines)); // allow subclass header handling $header = $this->handleHeader($header, $result, $typemap); // parse projection information in 'short syntax' if available if (trim($header) != '') { $result['fields'] = $this->helper->parseFieldsShort($header, $typemap); } $tree = $this->helper->constructTree($lines, 'query'); // parse long fields, if available $longFields = $this->helper->getFields($tree, $typemap); // check double data if (count($result['fields']) && count($longFields)) { $this->helper->_fail($this->getLang('error_query_bothfields')); } // assign longfields if necessary if (count($result['fields']) == 0) { $result['fields'] = $longFields; } // check no data if (count($result['fields']) == 0) { $this->helper->_fail($this->helper->getLang('error_query_noselect')); } // determine the variables to project $projection = array(); foreach ($result['fields'] as $f) { $projection[] = $f['variable']; } $projection = array_unique($projection); // allow subclass body handling $this->handleBody($tree, $result, $typemap); // parse UI group $this->handleUI($tree, $result, $typemap); // parse the query itself list($result['query'], $variables) = $this->helper->constructQuery($tree, $typemap, $projection); // allow subclass footer handling $footer = $this->handleFooter($footer, $result, $typemap, $variable); // check projected variables and load types foreach ($result['fields'] as $i => $f) { $var = $f['variable']; if (!in_array($var, $variables)) { $this->helper->_fail(sprintf($this->helper->getLang('error_query_unknownselect'), utf8_tohtml(hsc($var)))); } if (empty($f['type'])) { if (!empty($typemap[$var])) { $result['fields'][$i] = array_merge($result['fields'][$i], $typemap[$var]); } else { list($type, $hint) = $this->util->getDefaultType(); $result['fields'][$i]['type'] = $type; $result['fields'][$i]['hint'] = $hint; } } } return $result; } catch (strata_exception $e) { return array('error' => array('message' => $e->getMessage(), 'regions' => $e->getData(), 'lines' => $lines)); } }