From 735e3b01a211e515cf72a5de1468eaf4529c1d37 Mon Sep 17 00:00:00 2001 From: Peter Baratta Date: Mon, 12 Aug 2013 11:43:42 -0400 Subject: [PATCH] Create a new response type for Numerical/Formula Named `FormulaEquationInput` (name up for debate) - Based off ChemEqnIn - Add FormulaEquationInput in inputtypes.py - Add a call to a skeleton method for a preview javascript: - Queue up some MathJax - Put some ordering on the AJAX requests: add a parameter when the request was started, when it returns check that it isn't outdated before displaying the preview - Tests Note: we moved the `jsinput` tests and DISABLED them, because they were causing the tests to fail. --- common/lib/capa/capa/inputtypes.py | 104 ++++- common/lib/capa/capa/responsetypes.py | 37 +- .../capa/templates/formulaequationinput.html | 20 + .../capa/capa/tests/test_input_templates.py | 26 ++ common/lib/capa/capa/tests/test_inputtypes.py | 204 +++++++++- .../test_files/formularesponse_with_hint.xml | 2 +- .../lib/xmodule/xmodule/css/capa/display.scss | 14 +- .../xmodule/js/spec/problem/edit_spec.coffee | 8 +- .../xmodule/js/src/problem/edit.coffee | 2 +- .../templates/problem/forumularesponse.yaml | 6 +- .../templates/problem/latex_problem.yaml | 5 +- .../templates/problem/numericalresponse.yaml | 6 +- .../xmodule/tests/test_crowdsource_hinter.py | 6 +- .../spec/formula_equation_preview_spec.js | 379 ++++++++++++++++++ .../{jsinput/jsinput.js => jsinput_spec.js} | 2 +- .../capa/spec/{jsinput => }/mainfixture.html | 0 .../js/capa/src/formula_equation_preview.js | 161 ++++++++ rakelib/jasmine.rake | 1 + 18 files changed, 921 insertions(+), 62 deletions(-) create mode 100644 common/lib/capa/capa/templates/formulaequationinput.html create mode 100644 common/static/js/capa/spec/formula_equation_preview_spec.js rename common/static/js/capa/spec/{jsinput/jsinput.js => jsinput_spec.js} (97%) rename common/static/js/capa/spec/{jsinput => }/mainfixture.html (100%) create mode 100644 common/static/js/capa/src/formula_equation_preview.js diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index 29800a211b..9defd2c5e6 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -16,6 +16,8 @@ Module containing the problem elements which render into input objects - crystallography - vsepr_input - drag_and_drop +- formulaequationinput +- chemicalequationinput These are matched by *.html files templates/*.html which are mako templates with the actual html. @@ -47,6 +49,7 @@ import pyparsing from .registry import TagRegistry from chem import chemcalc +from preview import latex_preview import xqueue_interface from datetime import datetime @@ -531,7 +534,7 @@ class TextLine(InputTypeBase): is used e.g. for embedding simulations turned into questions. Example: - + This example will render out a text line with a math preview and the text 'm/s' after the end of the text line. @@ -1037,15 +1040,16 @@ class ChemicalEquationInput(InputTypeBase): result = {'preview': '', 'error': ''} - formula = data['formula'] - if formula is None: + try: + formula = data['formula'] + except KeyError: result['error'] = "No formula specified." return result try: result['preview'] = chemcalc.render_to_html(formula) except pyparsing.ParseException as p: - result['error'] = "Couldn't parse formula: {0}".format(p) + result['error'] = u"Couldn't parse formula: {0}".format(p.msg) except Exception: # this is unexpected, so log log.warning( @@ -1056,6 +1060,98 @@ class ChemicalEquationInput(InputTypeBase): registry.register(ChemicalEquationInput) +#------------------------------------------------------------------------- + + +class FormulaEquationInput(InputTypeBase): + """ + An input type for entering formula equations. Supports live preview. + + Example: + + + + options: size -- width of the textbox. + """ + + template = "formulaequationinput.html" + tags = ['formulaequationinput'] + + @classmethod + def get_attributes(cls): + """ + Can set size of text field. + """ + return [Attribute('size', '20'), ] + + def _extra_context(self): + """ + TODO (vshnayder): Get rid of 'previewer' once we have a standard way of requiring js to be loaded. + """ + # `reported_status` is basically `status`, except we say 'unanswered' + reported_status = '' + if self.status == 'unsubmitted': + reported_status = 'unanswered' + elif self.status in ('correct', 'incorrect', 'incomplete'): + reported_status = self.status + + return { + 'previewer': '/static/js/capa/src/formula_equation_preview.js', + 'reported_status': reported_status + } + + def handle_ajax(self, dispatch, get): + ''' + Since we only have formcalc preview this input, check to see if it + matches the corresponding dispatch and send it through if it does + ''' + if dispatch == 'preview_formcalc': + return self.preview_formcalc(get) + return {} + + def preview_formcalc(self, get): + """ + Render an preview of a formula or equation. `get` should + contain a key 'formula' with a math expression. + + Returns a json dictionary: + { + 'preview' : '' or '' + 'error' : 'the-error' or '' + 'request_start' :