danielebarchiesi@4: default_sem_html_formats = 'dc openid erdf rdfa posh-rdf microformats'; danielebarchiesi@4: $this->triples = array(); danielebarchiesi@4: $this->target_encoding = ''; danielebarchiesi@4: $this->t_count = 0; danielebarchiesi@4: $this->added_triples = array(); danielebarchiesi@4: $this->skip_dupes = false; danielebarchiesi@4: $this->bnode_prefix = $this->v('bnode_prefix', 'arc'.substr(md5(uniqid(rand())), 0, 4).'b', $this->a); danielebarchiesi@4: $this->bnode_id = 0; danielebarchiesi@4: $this->auto_extract = $this->v('auto_extract', 1, $this->a); danielebarchiesi@4: $this->extracted_formats = array(); danielebarchiesi@4: $this->cache = array(); danielebarchiesi@4: $this->detected_formats = array(); danielebarchiesi@4: $this->keep_cdata_ws = $this->v('keep_cdata_whitespace', 0, $this->a); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function x($re, $v, $options = 'si', $keep_ws = 0) { danielebarchiesi@4: list($ws, $v) = preg_match('/^(\s*)(.*)$/s', $v, $m) ? array($m[1], $m[2]) : array('', $v); danielebarchiesi@4: if (preg_match("/^" . $re . "(.*)$/" . $options, $v, $m)) { danielebarchiesi@4: if ($keep_ws) $m[1] = $ws . $m[1]; danielebarchiesi@4: return $m; danielebarchiesi@4: } danielebarchiesi@4: return false; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function setReader(&$reader) { danielebarchiesi@4: $this->reader = $reader; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function createBnodeID(){ danielebarchiesi@4: $this->bnode_id++; danielebarchiesi@4: return '_:' . $this->bnode_prefix . $this->bnode_id; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function addT($t) { danielebarchiesi@4: if (function_exists('html_entity_decode')) { danielebarchiesi@4: $t['o'] = html_entity_decode($t['o']); danielebarchiesi@4: } danielebarchiesi@4: if ($this->skip_dupes) { danielebarchiesi@4: $h = md5(serialize($t)); danielebarchiesi@4: if (!isset($this->added_triples[$h])) { danielebarchiesi@4: $this->triples[$this->t_count] = $t; danielebarchiesi@4: $this->t_count++; danielebarchiesi@4: $this->added_triples[$h] = true; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: else { danielebarchiesi@4: $this->triples[$this->t_count] = $t; danielebarchiesi@4: $this->t_count++; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function getTriples() { danielebarchiesi@4: return $this->v('triples', array()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function countTriples() { danielebarchiesi@4: return $this->t_count; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function getSimpleIndex($flatten_objects = 1, $vals = '') { danielebarchiesi@4: return ARC2::getSimpleIndex($this->getTriples(), $flatten_objects, $vals); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function parse($path, $data = '', $iso_fallback = 'ignore') { danielebarchiesi@4: $this->nodes = array(); danielebarchiesi@4: $this->node_count = 0; danielebarchiesi@4: $this->level = 0; danielebarchiesi@4: /* reader */ danielebarchiesi@4: if (!$this->v('reader')) { danielebarchiesi@4: ARC2::inc('Reader'); danielebarchiesi@4: $this->reader = new ARC2_Reader($this->a, $this); danielebarchiesi@4: } danielebarchiesi@4: $this->reader->setAcceptHeader('Accept: text/html, application/xhtml, */*; q=0.9'); danielebarchiesi@4: $this->reader->activate($path, $data); danielebarchiesi@4: $this->target_encoding = $this->reader->getEncoding(false); danielebarchiesi@4: $this->x_base = isset($this->a['base']) && $this->a['base'] ? $this->a['base'] : $this->reader->base; danielebarchiesi@4: $this->base = $this->x_base; danielebarchiesi@4: $this->doc_url = $this->reader->base; danielebarchiesi@4: /* parse */ danielebarchiesi@4: $rest = ''; danielebarchiesi@4: $this->cur_tag = ''; danielebarchiesi@4: while ($d = $this->reader->readStream(1)) { danielebarchiesi@4: $rest = $this->processData($rest . $d); danielebarchiesi@4: } danielebarchiesi@4: $this->reader->closeStream(); danielebarchiesi@4: unset($this->reader); danielebarchiesi@4: return $this->done(); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function getEncoding($src = 'ignore') { danielebarchiesi@4: return $this->target_encoding; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function done() { danielebarchiesi@4: if ($this->auto_extract) { danielebarchiesi@4: $this->extractRDF(); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function processData($v) { danielebarchiesi@4: $sub_v = $v; danielebarchiesi@4: do { danielebarchiesi@4: $proceed = 1; danielebarchiesi@4: if ((list($sub_r, $sub_v) = $this->xComment($sub_v)) && $sub_r) { danielebarchiesi@4: $this->open(0, 'comment', array('value' => $sub_r)); danielebarchiesi@4: $this->close(0, 'comment'); danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: if ((list($sub_r, $sub_v) = $this->xDoctype($sub_v)) && $sub_r) { danielebarchiesi@4: $this->open(0, 'doctype', array('value' => $sub_r)); danielebarchiesi@4: $this->close(0, 'doctype'); danielebarchiesi@4: /* RDFa detection */ danielebarchiesi@4: if (preg_match('/rdfa /i', $sub_r)) $this->detected_formats['rdfa'] = 1; danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: if ($this->level && ((list($sub_r, $sub_v) = $this->xWS($sub_v)) && $sub_r)) { danielebarchiesi@4: $this->cData(0, $sub_r); danielebarchiesi@4: } danielebarchiesi@4: elseif ((list($sub_r, $sub_v) = $this->xOpen($sub_v)) && $sub_r) { danielebarchiesi@4: $this->open(0, $sub_r['tag'], $sub_r['a']); danielebarchiesi@4: $this->cur_tag = $sub_r['tag']; danielebarchiesi@4: if ($sub_r['empty']) { danielebarchiesi@4: $this->close(0, $sub_r['tag'], 1); danielebarchiesi@4: $this->cur_tag = ''; danielebarchiesi@4: } danielebarchiesi@4: /* eRDF detection */ danielebarchiesi@4: if (!isset($this->detected_formats['erdf']) && isset($sub_r['a']['profile m']) && in_array('http://purl.org/NET/erdf/profile', $sub_r['a']['profile m'])) $this->detected_formats['erdf'] = 1; danielebarchiesi@4: /* poshRDF detection */ danielebarchiesi@4: if (!isset($this->detected_formats['posh-rdf']) && isset($sub_r['a']['class m']) && in_array('rdf-p', $sub_r['a']['class m'])) $this->detected_formats['posh-rdf'] = 1; danielebarchiesi@4: /* RDFa detection */ danielebarchiesi@4: if (!isset($this->detected_formats['rdfa']) && ($this->cur_tag == 'html') && isset($sub_r['a']['version m']) && in_array('XHTML+RDFa', $sub_r['a']['version m'])) $this->detected_formats['rdfa'] = 1; danielebarchiesi@4: if (!isset($this->detected_formats['rdfa']) && isset($sub_r['a']['xmlns']) && $sub_r['a']['xmlns'] && $this->isRDFNSDecl($sub_r['a']['xmlns'])) $this->detected_formats['rdfa'] = 1; danielebarchiesi@4: if (!isset($this->detected_formats['rdfa']) && array_intersect(array('about', 'typeof', 'property'), array_keys($sub_r['a']))) $this->detected_formats['rdfa'] = 1; danielebarchiesi@4: } danielebarchiesi@4: elseif ((list($sub_r, $sub_v) = $this->xClose($sub_v)) && $sub_r) { danielebarchiesi@4: if (preg_match('/^(area|base|br|col|frame|hr|input|img|link|xmeta|param)$/', $sub_r['tag'])) { danielebarchiesi@4: /* already implicitly closed */ danielebarchiesi@4: } danielebarchiesi@4: else { danielebarchiesi@4: $this->close(0, $sub_r['tag']); danielebarchiesi@4: $this->cur_tag = ''; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: elseif ((list($sub_r, $sub_v) = $this->xCData($sub_v)) && $sub_r) { danielebarchiesi@4: $this->cData(0, $sub_r); danielebarchiesi@4: } danielebarchiesi@4: else { danielebarchiesi@4: $proceed = 0; danielebarchiesi@4: } danielebarchiesi@4: } while ($proceed); danielebarchiesi@4: return $sub_v; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function isRDFNSDecl($ns) { danielebarchiesi@4: foreach ($ns as $k => $v) { danielebarchiesi@4: if ($k) return 1; danielebarchiesi@4: } danielebarchiesi@4: return 0; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function xComment($v) { danielebarchiesi@4: if ($r = $this->x('\<\!\-\-', $v)) { danielebarchiesi@4: if ($sub_r = $this->x('(.*)\-\-\>', $r[1], 'Us')) { danielebarchiesi@4: return array($sub_r[1], $sub_r[2]); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return array(0, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function xDoctype($v) { danielebarchiesi@4: if ($r = $this->x('\<\!DOCTYPE', $v)) { danielebarchiesi@4: if ($sub_r = $this->x('([^\>]+)\>', $r[1])) { danielebarchiesi@4: return array($sub_r[1], $sub_r[2]); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return array(0, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function xWS($v) { danielebarchiesi@4: if ($r = ARC2::x('(\s+)', $v)) { danielebarchiesi@4: return array($r[1], $r[2]); danielebarchiesi@4: } danielebarchiesi@4: return array(0, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function xOpen($v) { danielebarchiesi@4: if ($r = $this->x('\<([^\s\/\>]+)([^\>]*)\>', $v)) { danielebarchiesi@4: list($sub_r, $sub_v) = $this->xAttributes($r[2]); danielebarchiesi@4: return array(array('tag' => strtolower($r[1]), 'a' => $sub_r, 'empty' => $this->isEmpty($r[1], $r[2])), $r[3]); danielebarchiesi@4: } danielebarchiesi@4: return array(0, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function xAttributes($v) { danielebarchiesi@4: $r = array(); danielebarchiesi@4: while ((list($sub_r, $v) = $this->xAttribute($v)) && $sub_r) { danielebarchiesi@4: if ($sub_sub_r = $this->x('xmlns\:?(.*)', $sub_r['k'])) { danielebarchiesi@4: $this->nsDecl(0, $sub_sub_r[1], $sub_r['value']); danielebarchiesi@4: $r['xmlns'][$sub_sub_r[1]] = $sub_r['value']; danielebarchiesi@4: } danielebarchiesi@4: else { danielebarchiesi@4: $r[$sub_r['k']] = $sub_r['value']; danielebarchiesi@4: $r[$sub_r['k'] . ' m'] = $sub_r['values']; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return array($r, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function xAttribute($v) { danielebarchiesi@4: if ($r = $this->x('([^\s\=]+)\s*(\=)?\s*([\'\"]?)', $v)) { danielebarchiesi@4: if (!$r[2]) {/* no '=' */ danielebarchiesi@4: if ($r[1] == '/') { danielebarchiesi@4: return array(0, $r[4]); danielebarchiesi@4: } danielebarchiesi@4: return array(array('k' => $r[1], 'value' => 1, 'values' => array(1)), $r[4]); danielebarchiesi@4: } danielebarchiesi@4: if (!$r[3]) {/* no quots */ danielebarchiesi@4: if ($sub_r = $this->x('([^\s]+)', $r[4])) { danielebarchiesi@4: return array(array('k' => $r[1], 'value' => $sub_r[1], 'values' => array($sub_r[1])), $sub_r[2]); danielebarchiesi@4: } danielebarchiesi@4: return array(array('k' => $r[1], 'value' => '', 'values' => array()), $r[4]); danielebarchiesi@4: } danielebarchiesi@4: $val = ''; danielebarchiesi@4: $multi = 0; danielebarchiesi@4: $sub_v = $r[4]; danielebarchiesi@4: while ($sub_v && (!$sub_r = $this->x('(\x5c\\' .$r[3]. '|\\' .$r[3]. ')', $sub_v))) { danielebarchiesi@4: $val .= substr($sub_v, 0, 1); danielebarchiesi@4: $sub_v = substr($sub_v, 1); danielebarchiesi@4: } danielebarchiesi@4: $sub_v = $sub_v ? $sub_r[2] : $sub_v; danielebarchiesi@4: $vals = preg_split('/ /', $val); danielebarchiesi@4: return array(array('k' => $r[1], 'value' => $val, 'values' => $vals), $sub_v); danielebarchiesi@4: } danielebarchiesi@4: return array(0, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function isEmpty($t, $v) { danielebarchiesi@4: if (preg_match('/^(area|base|br|col|frame|hr|input|img|link|xmeta|param)$/', $t)) { danielebarchiesi@4: return 1; danielebarchiesi@4: } danielebarchiesi@4: if (preg_match('/\/$/', $v)) { danielebarchiesi@4: return 1; danielebarchiesi@4: } danielebarchiesi@4: return 0; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function xClose($v) { danielebarchiesi@4: if ($r = $this->x('\<\/([^\s\>]+)\>', $v)) { danielebarchiesi@4: return array(array('tag' => strtolower($r[1])), $r[2]); danielebarchiesi@4: } danielebarchiesi@4: return array(0, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function xCData($v) { danielebarchiesi@4: if (preg_match('/(script|style)/i', $this->cur_tag)) { danielebarchiesi@4: if ($r = $this->x('(.+)(\<\/' . $this->cur_tag . '\>)', $v, 'Uis')) { danielebarchiesi@4: return array($r[1], $r[2] . $r[3]); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: elseif ($r = $this->x('([^\<]+)', $v, 'si', $this->keep_cdata_ws)) { danielebarchiesi@4: return array($r[1], $r[2]); danielebarchiesi@4: } danielebarchiesi@4: return array(0, $v); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function extractRDF($formats = '') { danielebarchiesi@4: $this->node_index = $this->getNodeIndex(); danielebarchiesi@4: $formats = !$formats ? $this->v('sem_html_formats', $this->default_sem_html_formats, $this->a) : $formats; danielebarchiesi@4: $formats = preg_split('/ /', $formats); danielebarchiesi@4: foreach ($formats as $format) { danielebarchiesi@4: if (!in_array($format, $this->extracted_formats)) { danielebarchiesi@4: $comp = $this->camelCase($format) . 'Extractor'; danielebarchiesi@4: if (ARC2::inc($comp)) { danielebarchiesi@4: $cls = 'ARC2_' . $comp; danielebarchiesi@4: $e = new $cls($this->a, $this); danielebarchiesi@4: $e->extractRDF(); danielebarchiesi@4: } danielebarchiesi@4: $this->extracted_formats[] = $format; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function getNode($id) { danielebarchiesi@4: return isset($this->nodes[$id]) ? $this->nodes[$id] : 0; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: }