public function test_substring_between()
 {
     $this->assertEquals(array('[hello]', 0, 6), stack_utils::substring_between('[hello] world!', '[', ']'));
     $this->assertEquals(array('[world]', 6, 12), stack_utils::substring_between('hello [world]!', '[', ']'));
     $this->assertEquals(array('[world]', 8, 14), stack_utils::substring_between('[hello] [world]!', '[', ']', 8));
     $this->assertEquals(array('[world]', 8, 14), stack_utils::substring_between('[hello] [world]!', '[', ']', 1));
     $this->assertEquals(array('$hello$', 0, 6), stack_utils::substring_between('$hello$ world!', '$', '$'));
     $this->assertEquals(array('$world$', 6, 12), stack_utils::substring_between('hello $world$!', '$', '$'));
     $this->assertEquals(array('$world$', 8, 14), stack_utils::substring_between('$hello$ $world$!', '$', '$', 8));
     $this->assertEquals(array('$ $', 6, 8), stack_utils::substring_between('$hello$ $world$!', '$', '$', 1));
     $this->assertEquals(array('[he[ll]o]', 0, 8), stack_utils::substring_between('[he[ll]o] world!', '[', ']'));
     $this->assertEquals(array('[[[]w[o]r[[l]d]]]', 6, 22), stack_utils::substring_between('hello [[[]w[o]r[[l]d]]]!', '[', ']'));
 }
 /**
  * This function checks chained inequalities
  * If we have two or more inequality symbols then we must have a logical connection {or/and} between each pair.
  * First we need to split over commas to break up lists etc.
  */
 private function check_chained_inequalities($ex)
 {
     if (substr_count($ex, '<') + substr_count($ex, '>') < 2) {
         return true;
     }
     // Plots, and HTML elements are protected within strings when they come back through the CAS.
     $found = stack_utils::substring_between($ex, '<html>', '</html>');
     if ($found[1] > 0) {
         $ex = str_replace($found[0], '', $ex);
     }
     // Separate out lists, sets, etc.
     $exsplit = explode(',', $ex);
     $bits = array();
     $ok = true;
     foreach ($exsplit as $bit) {
         $ok = $ok && $this->check_chained_inequalities_ind($bit);
     }
     return $ok;
 }
 protected function unpack_helper($rawresultfragment)
 {
     // Take the raw string from the CAS, and unpack this into an array.
     $offset = 0;
     $rawresultfragmentlen = strlen($rawresultfragment);
     $unparsed = '';
     $errors = '';
     if ($eqpos = strpos($rawresultfragment, '=', $offset)) {
         // Check there are ='s.
         do {
             $gb = stack_utils::substring_between($rawresultfragment, '[', ']', $eqpos);
             $val = substr($gb[0], 1, strlen($gb[0]) - 2);
             $val = trim($val);
             if (preg_match('/[-A-Za-z0-9].*/', substr($rawresultfragment, $offset, $eqpos - $offset), $regs)) {
                 $var = trim($regs[0]);
             } else {
                 $var = 'errors';
                 $errors['LOCVARNAME'] = "Couldn't get the name of the local variable.";
             }
             $unparsed[$var] = $val;
             $offset = $gb[2];
         } while (($eqpos = strpos($rawresultfragment, '=', $offset)) && $offset < $rawresultfragmentlen);
     } else {
         $errors['PREPARSE'] = "There are no ='s in the raw output from the CAS!";
     }
     if ('' != $errors) {
         $unparsed['errors'] = $errors;
     }
     return $unparsed;
 }