public function test_maths_rendering()
 {
     if (!stack_maths_output_maths::filter_is_installed()) {
         $this->markTestSkipped('The OU maths filter is not installed.');
     }
     if (!defined('FILTER_MATHS_TEST_SERVICE_URL_BASE')) {
         $this->markTestSkipped('To run the OU maths filter output tests, ' . 'you must define FILTER_MATHS_TEST_SERVICE_URL_BASE in config.php.');
     }
     $this->resetAfterTest();
     set_config('mathsdisplay', 'maths', 'qtype_stack');
     set_config('texservice', FILTER_MATHS_TEST_SERVICE_URL_BASE . 'tex', 'filter_maths');
     set_config('imageservice', FILTER_MATHS_TEST_SERVICE_URL_BASE . 'imagetex', 'filter_maths');
     set_config('englishservice', FILTER_MATHS_TEST_SERVICE_URL_BASE . 'english', 'filter_maths');
     stack_utils::clear_config_cache();
     filter_set_global_state('mathjaxloader', TEXTFILTER_DISABLED);
     // Test language string.
     $this->assertRegExp('~^Your answer needs to be a single fraction of the form <a .*alt="a over b".*</a>\\. $~', stack_string('ATSingleFrac_part'));
     // Test docs - make sure maths inside <code> is not rendered.
     $this->assertRegExp('~^<p><code>\\\\\\(x\\^2\\\\\\)</code> gives <a .*alt="x squared".*</a>\\.</p>\\n$~', stack_docs_render_markdown('<code>\\(x^2\\)</code> gives \\(x^2\\).', ''));
     // Test docs - make sure maths inside <textarea> is not rendered.
     $this->assertRegExp('~^<p>\\n' . 'Differentiate \\\\\\\\\\[x\\^2 \\+ y\\^2\\\\\\\\\\] with respect to \\\\\\\\\\(x\\\\\\\\\\).</p>\\n$~', stack_docs_render_markdown('<textarea readonly="readonly" rows="3" cols="50">' . "\n" . 'Differentiate \\[x^2 + y^2\\] with respect to \\(x\\).</textarea>', ''));
     // Test CAS text with inline maths.
     $this->assertEquals('What is &lt;tex mode="inline"&gt;x^2&lt;/tex&gt;?', stack_maths::process_display_castext('What is \\(x^2\\)?'));
     // Test CAS text with display maths.
     $this->assertEquals('What is <span class="displayequation">&lt;tex mode="display"&gt;x^2&lt;/tex&gt;</span>?', stack_maths::process_display_castext('What is \\[x^2\\]?'));
     // Test with replacedollars.
     set_config('replacedollars', '1', 'qtype_stack');
     stack_utils::clear_config_cache();
     $this->assertEquals('What is &lt;tex mode="inline"&gt;x^2&lt;/tex&gt; or ' . '<span class="displayequation">&lt;tex mode="display"&gt;x^2&lt;/tex&gt;</span>?', stack_maths::process_display_castext('What is $x^2$ or $$x^2$$?'));
     stack_utils::clear_config_cache();
 }
 public function test_maths_output_mathsjax()
 {
     filter_set_global_state('mathjaxloader', TEXTFILTER_DISABLED);
     // MathJax output is the default.
     $this->assertEquals('Your answer needs to be a single fraction of the form \\( {a}\\over{b} \\). ', stack_string('ATSingleFrac_part'));
     $this->assertEquals("<p><code>\\(x^2\\)</code> gives \\(x^2\\).</p>\n", stack_docs_render_markdown('`\\(x^2\\)` gives \\(x^2\\).', ''));
     $this->assertEquals('What is \\(x^2\\)?', stack_maths::process_display_castext('What is \\(x^2\\)?'));
     $this->resetAfterTest();
     set_config('replacedollars', '1', 'qtype_stack');
     stack_utils::clear_config_cache();
     $this->assertEquals('What is \\(x^2\\) or \\[x^2\\]?', stack_maths::process_display_castext('What is $x^2$ or $$x^2$$?'));
     stack_utils::clear_config_cache();
 }
 /**
  * Replace any $...$ and $$...$$ delimiters in the question text from the
  * form with the recommended delimiters.
  * @param object $fromform the data from the form.
  */
 protected function fix_dollars_in_form_data($fromform)
 {
     $questionfields = array('questiontext', 'generalfeedback', 'specificfeedback', 'prtcorrect', 'prtpartiallycorrect', 'prtincorrect');
     foreach ($questionfields as $field) {
         $fromform->{$field}['text'] = stack_maths::replace_dollars($fromform->{$field}['text']);
     }
     $fromform->questionnote = stack_maths::replace_dollars($fromform->questionnote);
     $prtnames = stack_utils::extract_placeholders($fromform->questiontext['text'] . $fromform->specificfeedback['text'], 'feedback');
     foreach ($prtnames as $prt) {
         foreach ($fromform->{$prt . 'truefeedback'} as &$feedback) {
             $feedback['text'] = stack_maths::replace_dollars($feedback['text']);
         }
         foreach ($fromform->{$prt . 'falsefeedback'} as &$feedback) {
             $feedback['text'] = stack_maths::replace_dollars($feedback['text']);
         }
     }
     foreach ($fromform->hint as &$hint) {
         $hint['text'] = stack_maths::replace_dollars($hint['text']);
     }
 }
 public function test_tex_rendering()
 {
     $this->resetAfterTest();
     set_config('mathsdisplay', 'tex', 'qtype_stack');
     stack_utils::clear_config_cache();
     filter_set_global_state('mathjaxloader', TEXTFILTER_DISABLED);
     // Test language string.
     // The <span class="MathJax_Preview"> bit is something that got added in
     // Moodle 2.8, so match it optionally.
     $this->assertRegExp('~^Your answer needs to be a single fraction of the form ' . '(<span class="MathJax_Preview">)?<a .*alt=" \\{a\\}\\\\over\\{b\\} ".*</(a|script)> \\. ~', stack_string('ATSingleFrac_part'));
     // Test docs - make sure maths inside <code> is not rendered.
     $this->assertRegExp('~^<p><code>\\\\\\(x\\^2\\\\\\)</code> gives (<span class="MathJax_Preview">)?<a .*alt="x\\^2".*</(a|script)> \\.</p>\\n$~', stack_docs_render_markdown('<code>\\(x^2\\)</code> gives \\(x^2\\).', ''));
     // Test docs - make sure maths inside <textarea> is not rendered.
     $this->assertRegExp('~^<p>\\n' . 'Differentiate \\\\\\\\\\[x\\^2 \\+ y\\^2\\\\\\\\\\] with respect to \\\\\\\\\\(x\\\\\\\\\\).</p>\\n$~', stack_docs_render_markdown('<textarea readonly="readonly" rows="3" cols="50">' . "\n" . 'Differentiate \\[x^2 + y^2\\] with respect to \\(x\\).</textarea>', ''));
     // Test CAS text with inline maths.
     $this->assertEquals('What is \\[x^2\\]?', stack_maths::process_display_castext('What is \\(x^2\\)?'));
     // Test CAS text with display maths.
     $this->assertEquals('What is <span class="displayequation">\\[\\displaystyle x^2\\]</span>?', stack_maths::process_display_castext('What is \\[x^2\\]?'));
     // Test with replacedollars.
     set_config('replacedollars', '1', 'qtype_stack');
     stack_utils::clear_config_cache();
     $this->assertEquals('What is \\[x^2\\] or <span class="displayequation">\\[\\displaystyle x^2\\]</span>?', stack_maths::process_display_castext('What is $x^2$ or $$x^2$$?'));
     stack_utils::clear_config_cache();
 }
$summary = array();
// LaTeX.
echo $OUTPUT->heading(stack_string('healthchecklatex'), 3);
echo html_writer::tag('p', stack_string('healthcheckmathsdisplaymethod', stack_maths::configured_output_name()));
echo html_writer::tag('p', stack_string('healthchecklatexintro'));
echo html_writer::tag('dt', stack_string('texdisplaystyle'));
echo html_writer::tag('dd', format_text(stack_string('healthchecksampledisplaytex')));
echo html_writer::tag('dt', stack_string('texinlinestyle'));
echo html_writer::tag('dd', format_text(stack_string('healthchecksampleinlinetex')));
if ($config->mathsdisplay === 'mathjax') {
    $settingsurl = new moodle_url('/admin/settings.php', array('section' => 'additionalhtml'));
    echo html_writer::tag('p', stack_string('healthchecklatexmathjax', $settingsurl->out()));
    echo html_writer::tag('textarea', s(stack_maths_output_mathjax::get_mathjax_code()), array('readonly' => 'readonly', 'wrap' => 'virtual', 'rows' => '12', 'cols' => '100'));
} else {
    $settingsurl = new moodle_url('/admin/filters.php');
    echo html_writer::tag('p', stack_string('healthcheckfilters', array('filter' => stack_maths::configured_output_name(), 'url' => $settingsurl->out())));
}
// Maxima config.
echo $OUTPUT->heading(stack_string('healthcheckconfig'), 3);
// Try to list available versions of Maxima (linux only, without the DB).
$connection = stack_connection_helper::make();
if (is_a($connection, 'stack_cas_connection_unix')) {
    echo html_writer::tag('pre', $connection->get_maxima_available());
}
// Check for location of Maxima.
$maximalocation = stack_cas_configuration::confirm_maxima_win_location();
if ('' != $maximalocation) {
    $message = stack_string('healthcheckconfigintro1') . ' ' . html_writer::tag('tt', $maximalocation);
    echo html_writer::tag('p', $message);
    $summary[] = array(null, $message);
}
    }
    set_time_limit(30);
    list($passed, $phpvalid, $phpcasstring, $error, $casvalid, $caserrors, $casdisplay, $casvalue, $answernote) = stack_inputvalidation_test_data::run_test($test);
    $allpassed = $allpassed && $passed;
    if ($passed) {
        $class = 'pass';
        $passedcol = stack_string('testsuitepass');
    } else {
        $class = 'fail';
        $passedcol = stack_string('testsuitefail');
    }
    $display = '';
    if ('' != $casdisplay) {
        $display = '\\(' . $casdisplay . '\\)';
    }
    $row = array('passed' => $passedcol, 'studentanswer' => s($test->rawstring), 'phpvalid' => s($phpvalid), 'phpcasstring' => s($phpcasstring), 'answernote' => $answernote, 'error' => $error, 'casvalid' => s($casvalid), 'casvalue' => $casvalue, 'casdisplay' => format_text(stack_maths::process_lang_string(s($display))) . html_writer::tag('pre', s($casdisplay)), 'caserrors' => $caserrors);
    $table->add_data_keyed($row, $class);
    flush();
}
$table->finish_output();
// Overall summary.
$took = microtime(true) - $start;
$rtook = round($took, 5);
$pertest = round($took / $notests, 5);
echo '<p>' . stack_string('testsuitenotests', array('no' => $notests));
echo '<br/>' . stack_string('testsuiteteststook', array('time' => $rtook));
echo '<br/>' . stack_string('testsuiteteststookeach', array('time' => $pertest));
echo '</p>';
$config = get_config('qtype_stack');
echo html_writer::tag('p', stack_string('healthcheckcache_' . $config->casresultscache));
// Overall summary.
 public function fix_maths_delimiters($text)
 {
     return stack_maths::replace_dollars($text);
 }
Example #8
0
/**
 * @param string $page countent in Markdown format.
 * @param string $docscontent base URL for linking to images etc.
 * @return string HTML content.
 */
function stack_docs_render_markdown($page, $docscontent)
{
    // Put in links to images etc.
    $page = preg_replace('~(?<!\\\\)%CONTENT~', $docscontent, $page);
    $page = str_replace('\\%CONTENT', '%CONTENT', $page);
    $page = stack_maths::pre_process_docs_page($page);
    if (strpos($page, '[[ALL_FACTS]]') > 0) {
        $page = str_replace('[[ALL_FACTS]]', stack_fact_sheets::generate_docs(), $page);
    }
    $page = format_text($page, $format = FORMAT_MARKDOWN);
    $page = stack_maths::post_process_docs_page($page);
    return $page;
}
 public function test_fact_sheets()
 {
     $cs2 = new stack_cas_session(array(), null, 0);
     $at1 = new stack_cas_text("[[facts:calc_diff_linearity_rule]]", $cs2, 0);
     $output = stack_maths::process_display_castext($at1->get_display_castext());
     $this->assertContains(stack_string('calc_diff_linearity_rule_name'), $output);
     $this->assertContains(stack_string('calc_diff_linearity_rule_fact'), $output);
 }
 /**
  * Update maths delimiters in one field of an object, outputting the before
  * and after HTML for review.
  * @param stdClass $question an object.
  * @param field $field the name of one of its fields.
  * @return boolean whether any change was made to the field.
  */
 public function fix_question_field($question, $field)
 {
     $newtext = stack_maths::replace_dollars($question->{$field});
     if ($newtext == $question->{$field}) {
         return false;
     }
     $markedup = stack_maths::replace_dollars($question->{$field}, '<ins>', '</ins>');
     echo html_writer::tag('p', stack_string('replacedollarsin', $field));
     echo html_writer::tag('pre', str_replace($this->search, $this->replace, s($markedup)), array('class' => 'questiontext'));
     echo html_writer::tag('div', stack_ouput_castext($newtext), array('class' => 'questiontext'));
     $question->{$field} = $newtext;
     return true;
 }
Example #11
0
/**
 * Equivalent to get_string($key, 'qtype_stack', $a), but this method ensure that
 * any equations in the string are displayed properly.
 * @param string $key the string name.
 * @param mixed $a (optional) any values to interpolate into the string.
 * @return string the language string
 */
function stack_string($key, $a = null)
{
    return stack_maths::process_lang_string(get_string($key, 'qtype_stack', $a));
}
Example #12
0
 public function general_feedback(question_attempt $qa)
 {
     $question = $qa->get_question();
     if (empty($question->generalfeedback)) {
         return '';
     }
     return $qa->get_question()->format_text(stack_maths::process_display_castext($question->get_generalfeedback_castext()->get_display_castext(), $this), $question->generalfeedbackformat, $qa, 'question', 'generalfeedback', $question->id);
 }
Example #13
0
    question_require_capability_on($questiondata, 'view');
}
$context = context_system::instance();
$PAGE->set_context($context);
$PAGE->set_url('/question/type/stack/caschat.php', $urlparams);
$title = stack_string('chattitle');
$PAGE->set_title($title);
$debuginfo = '';
$errs = '';
$varerrs = '';
$vars = optional_param('vars', '', PARAM_RAW);
$string = optional_param('cas', '', PARAM_RAW);
$simp = optional_param('simp', '', PARAM_RAW);
// Always fix dollars in this script.
// Very useful for converting existing text for use elswhere in Moodle, such as in pages of text.
$string = stack_maths::replace_dollars($string);
// Sort out simplification.
if ('on' == $simp) {
    $simp = true;
} else {
    $simp = false;
}
// Initially simplification should be on.
if (!$vars and !$string) {
    $simp = true;
}
if ($string) {
    $options = new stack_options();
    $options->set_site_defaults();
    $options->set_option('simplify', $simp);
    $session = new stack_cas_session(null, $options);