function meth_Locator_FindParallel(&$Txt, $ZoneBeg, $ZoneEnd, $ConfId) { // Define configurations global $_TBS_ParallelLst, $_TBS_BlockAlias; if (!isset($_TBS_ParallelLst)) { $_TBS_ParallelLst = array(); } if ($ConfId == 'tbs:table' && !isset($_TBS_ParallelLst['tbs:table'])) { $_TBS_ParallelLst['tbs:table'] = array('parent' => 'table', 'ignore' => array('!--', 'caption', 'thead', 'thbody', 'thfoot'), 'cols' => array(), 'rows' => array('tr'), 'cells' => array('td' => 'colspan', 'th' => 'colspan')); } if (!isset($_TBS_ParallelLst[$ConfId])) { return $this->meth_Misc_Alert("Parallel", "The configuration '{$ConfId}' is not found."); } $conf = $_TBS_ParallelLst[$ConfId]; $Parent = $conf['parent']; // Search parent bounds $par_o = clsTinyButStrong::f_Xml_FindTag($Txt, $Parent, true, $ZoneBeg, false, 1, false); if ($par_o === false) { return $this->meth_Misc_Alert("Parallel", "The opening tag '{$Parent}' is not found."); } $par_c = clsTinyButStrong::f_Xml_FindTag($Txt, $Parent, false, $ZoneBeg, true, -1, false); if ($par_c === false) { return $this->meth_Misc_Alert("Parallel", "The closing tag '{$Parent}' is not found."); } $SrcPOffset = $par_o->PosEnd + 1; $SrcP = substr($Txt, $SrcPOffset, $par_c->PosBeg - $SrcPOffset); // temporary variables $tagR = ''; $tagC = ''; $z = ''; $pRO = false; $pROe = false; $pCO = false; $pCOe = false; $p = false; $Loc = new clsTbsLocator(); $Rows = array(); $RowIdx = 0; $RefRow = false; $RefCellB = false; $RefCellE = false; $RowType = array(); // Loop on entities inside the parent entity $PosR = 0; $mode_column = true; $Cells = array(); $ColNum = 1; $IsRef = false; // Search for the next Row Opening tag while (clsTinyButStrong::f_Xml_GetNextEntityName($SrcP, $PosR, $tagR, $pRO, $p)) { $pROe = strpos($SrcP, '>', $p) + 1; $singleR = $SrcP[$pROe - 2] === '/'; // If the tag is not a closing, a self-closing and has a name if ($tagR !== '') { if (in_array($tagR, $conf['ignore'])) { // This tag must be ignored $PosR = $p; } elseif (isset($conf['cols'][$tagR])) { // Column definition that must be merged as a cell if ($mode_column === false) { return $this->meth_Misc_Alert("Parallel", "There is a column definition ({$tagR}) after a row (" . $Rows[$RowIdx - 1]['tag'] . ")."); } if (isset($RowType['_column'])) { $RowType['_column']++; } else { $RowType['_column'] = 1; } $att = $conf['cols'][$tagR]; $this->meth_Locator_FindParallelCol($SrcP, $PosR, $tagR, $pRO, $p, $SrcPOffset, $RowIdx, $ZoneBeg, $ZoneEnd, $att, $Loc, $Cells, $ColNum, $IsRef, $RefCellB, $RefCellE, $RefRow); } elseif (!$singleR) { // Search the Row Closing tag $locRE = clsTinyButStrong::f_Xml_FindTag($SrcP, $tagR, false, $pROe, true, -1, false); if ($locRE === false) { return $this->meth_Misc_Alert("Parallel", "The row closing tag is not found. (tagR={$tagR}, p={$p}, pROe={$pROe})"); } // Inner source $SrcR = substr($SrcP, $pROe, $locRE->PosBeg - $pROe); $SrcROffset = $SrcPOffset + $pROe; if (in_array($tagR, $conf['rows'])) { if ($mode_column && isset($RowType['_column'])) { $Rows[$RowIdx] = array('tag' => '_column', 'cells' => $Cells, 'isref' => $IsRef, 'count' => $RowType['_column']); $RowIdx++; } $mode_column = false; if (isset($RowType[$tagR])) { $RowType[$tagR]++; } else { $RowType[$tagR] = 1; } // Now we've got the row entity, we search for cell entities $Cells = array(); $ColNum = 1; $PosC = 0; $IsRef = false; // Loop on Cell Opening tags while (clsTinyButStrong::f_Xml_GetNextEntityName($SrcR, $PosC, $tagC, $pCO, $p)) { if (isset($conf['cells'][$tagC])) { $att = $conf['cells'][$tagC]; $this->meth_Locator_FindParallelCol($SrcR, $PosC, $tagC, $pCO, $p, $SrcROffset, $RowIdx, $ZoneBeg, $ZoneEnd, $att, $Loc, $Cells, $ColNum, $IsRef, $RefCellB, $RefCellE, $RefRow); } else { $PosC = $p; } } $Rows[$RowIdx] = array('tag' => $tagR, 'cells' => $Cells, 'isref' => $IsRef, 'count' => $RowType[$tagR]); $RowIdx++; } $PosR = $locRE->PosEnd; } else { $PosR = $pROe; } } else { $PosR = $pROe; } } //return $Rows; $Blocks = array(); $rMax = count($Rows) - 1; foreach ($Rows as $r => $Row) { $Cells = $Row['cells']; if (isset($Cells[$RefCellB]) && $Cells[$RefCellB]['IsBegin']) { if (isset($Cells[$RefCellE]) && $Cells[$RefCellE]['IsEnd']) { $PosBeg = $Cells[$RefCellB]['PosBeg']; $PosEnd = $Cells[$RefCellE]['PosEnd']; $Blocks[$r] = array('PosBeg' => $PosBeg, 'PosEnd' => $PosEnd, 'IsRef' => $Row['isref'], 'Src' => substr($Txt, $PosBeg, $PosEnd - $PosBeg + 1)); } else { return $this->meth_Misc_Alert("Parallel", "At row " . $Row['count'] . " having entity [" . $Row['tag'] . "], the column {$RefCellE} is missing or is not the last in a set of spanned columns. (The block is defined from column {$RefCellB} to {$RefCellE})"); } } else { return $this->meth_Misc_Alert("Parallel", "At row " . $Row['count'] . " having entity [" . $Row['tag'] . "],the column {$RefCellB} is missing or is not the first in a set of spanned columns. (The block is defined from column {$RefCellB} to {$RefCellE})"); } } return $Blocks; }