Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alex/add latex compiler key #1514

Merged
merged 1 commit into from
Nov 4, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Blades: Disallow users to enter video url's in http.

LMS: Improve the acessibility of the forum follow post buttons.

Blades: Latex problems are now enabled via use_latex_compiler
key in course settings. (BLD-426)

Blades: Fix bug when the speed can only be changed when the video is playing.

LMS: Change bulk email implementation to use less memory, and to better handle
Expand Down
25 changes: 23 additions & 2 deletions cms/djangoapps/contentstore/features/component.feature
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,19 @@ Feature: CMS.Component Adding
| Component |
| Text |
| Announcement |
| E-text Written in LaTeX |
Then I see HTML components in this order:
| Component |
| Text |
| Announcement |

Scenario: I can add Latex HTML components
Given I am in Studio editing a new unit
Given I have enabled latex compiler
When I add this type of HTML component:
| Component |
| E-text Written in LaTeX |
Then I see HTML components in this order:
| Component |
| E-text Written in LaTeX |

Scenario: I can add Common Problem components
Expand Down Expand Up @@ -58,9 +66,22 @@ Feature: CMS.Component Adding
| Drag and Drop |
| Image Mapped Input |
| Math Expression Input |
| Problem Written in LaTeX |
| Problem with Adaptive Hint |


Scenario: I can add Advanced Latex Problem components
Given I am in Studio editing a new unit
Given I have enabled latex compiler
When I add a "<Component>" "Advanced Problem" component
Then I see a "<Component>" Problem component
# Flush out the database before the next example executes
And I reset the database
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary -- the teardown method of the test should always do this regardless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singingwolfboy This comes from latest commit in master (this week), see Scenario: I can add Advanced Problem components. It was added by @jzoldak 28.10 in edx/edx-platform@380e7c4

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is an unfortunate and sub-obtimal pattern that we don't want to proliferate but are letting go for now. :(
Lettuce has hooks for after_step and after_scenario, but no hook for after_example. The right way to solve this, given the way we have set up our acceptance tests, is to add an after_example hook to our fork of lettuce and submit an upstream PR to the official repo.
I have created a ticket in the testeng backlog for this.


Examples:
| Component |
| Problem Written in LaTeX |
| Problem with Adaptive Hint in Latex |

Scenario: I see a prompt on delete
Given I am in Studio editing a new unit
And I add a "Discussion" "single step" component
Expand Down
1 change: 1 addition & 0 deletions cms/djangoapps/contentstore/features/html-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def i_see_only_the_html_display_name(step):
@step('I have created an E-text Written in LaTeX$')
def i_created_etext_in_latex(step):
world.create_course_with_unit()
step.given('I have enabled latex compiler')
world.create_component_instance(
step=step,
category='html',
Expand Down
11 changes: 11 additions & 0 deletions cms/djangoapps/contentstore/features/problem-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from lettuce import world, step
from nose.tools import assert_equal, assert_true # pylint: disable=E0611
from common import type_in_codemirror, open_new_course
from advanced_settings import change_value
from course_import import import_file, go_to_import
from selenium.webdriver.common.keys import Keys

Expand Down Expand Up @@ -159,9 +160,19 @@ def cancel_does_not_save_changes(step):
step.given("I see the advanced settings and their expected values")


@step('I have enabled latex compiler')
def enable_latex_compiler(step):
url = world.browser.url
step.given("I select the Advanced Settings")
change_value(step, 'use_latex_compiler', True)
world.visit(url)
world.wait_for_xmodule()


@step('I have created a LaTeX Problem')
def create_latex_problem(step):
world.create_course_with_unit()
step.given('I have enabled latex compiler')
world.create_component_instance(
step=step,
category='problem',
Expand Down
14 changes: 8 additions & 6 deletions cms/djangoapps/contentstore/views/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,14 @@ def edit_unit(request, location):
# add boilerplates
if hasattr(component_class, 'templates'):
for template in component_class.templates():
component_templates[category].append((
template['metadata'].get('display_name'),
category,
template['metadata'].get('markdown') is not None,
template.get('template_id')
))
filter_templates = getattr(component_class, 'filter_templates', None)
if not filter_templates or filter_templates(template, course):
component_templates[category].append((
template['metadata'].get('display_name'),
category,
template['metadata'].get('markdown') is not None,
template.get('template_id')
))

# Check if there are any advanced modules specified in the course policy.
# These modules should be specified as a list of strings, where the strings
Expand Down
2 changes: 1 addition & 1 deletion cms/templates/widgets/metadata-edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<%static:include path="js/metadata-list-entry.underscore" />
</script>

<% showHighLevelSource='source_code' in editable_metadata_fields and editable_metadata_fields['source_code']['explicitly_set'] %>
<% showHighLevelSource='source_code' in editable_metadata_fields and editable_metadata_fields['source_code']['explicitly_set'] and enable_latex_compiler %>
<% metadata_field_copy = copy.copy(editable_metadata_fields) %>
## Delete 'source_code' field (if it exists) so metadata editor view does not attempt to render it.
% if 'source_code' in editable_metadata_fields:
Expand Down
33 changes: 28 additions & 5 deletions common/lib/xmodule/xmodule/capa_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ class CapaFields(object):
# TODO: someday it should be possible to not duplicate this definition here
# and in inheritance.py
)
use_latex_compiler = Boolean(
help="Enable LaTeX templates?",
default=False,
scope=Scope.settings
)


class CapaModule(CapaFields, XModule):
Expand Down Expand Up @@ -1174,10 +1179,23 @@ class CapaDescriptor(CapaFields, RawDescriptor):
metadata_translations = dict(RawDescriptor.metadata_translations)
metadata_translations['attempts'] = 'max_attempts'

@classmethod
def filter_templates(cls, template, course):
"""
Filter template that contains 'latex' from templates.

Show them only if use_latex_compiler is set to True in
course settings.
"""
return (not 'latex' in template['template_id'] or course.use_latex_compiler)

def get_context(self):
_context = RawDescriptor.get_context(self)
_context.update({'markdown': self.markdown,
'enable_markdown': self.markdown is not None})
_context.update({
'markdown': self.markdown,
'enable_markdown': self.markdown is not None,
'enable_latex_compiler': self.use_latex_compiler,
})
return _context

# VS[compat]
Expand All @@ -1193,9 +1211,14 @@ def backcompat_paths(cls, path):
@property
def non_editable_metadata_fields(self):
non_editable_fields = super(CapaDescriptor, self).non_editable_metadata_fields
non_editable_fields.extend([CapaDescriptor.due, CapaDescriptor.graceperiod,
CapaDescriptor.force_save_button, CapaDescriptor.markdown,
CapaDescriptor.text_customization])
non_editable_fields.extend([
CapaDescriptor.due,
CapaDescriptor.graceperiod,
CapaDescriptor.force_save_button,
CapaDescriptor.markdown,
CapaDescriptor.text_customization,
CapaDescriptor.use_latex_compiler,
])
return non_editable_fields

# Proxy to CapaModule for access to any of its attributes
Expand Down
28 changes: 26 additions & 2 deletions common/lib/xmodule/xmodule/html_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from path import path

from pkg_resources import resource_string
from xblock.fields import Scope, String
from xblock.fields import Scope, String, Boolean
from xmodule.editing_module import EditingDescriptor
from xmodule.html_checker import check_html
from xmodule.stringify import stringify_children
Expand All @@ -30,6 +30,11 @@ class HtmlFields(object):
)
data = String(help="Html contents to display for this module", default=u"", scope=Scope.content)
source_code = String(help="Source code for LaTeX documents. This feature is not well-supported.", scope=Scope.settings)
use_latex_compiler = Boolean(
help="Enable LaTeX templates?",
default=False,
scope=Scope.settings
)


class HtmlModule(HtmlFields, XModule):
Expand Down Expand Up @@ -82,6 +87,16 @@ def backcompat_paths(cls, path):
nc.append(candidate[:-4] + '.html')
return candidates + nc

@classmethod
def filter_templates(cls, template, course):
"""
Filter template that contains 'latex' from templates.

Show them only if use_latex_compiler is set to True in
course settings.
"""
return (not 'latex' in template['template_id'] or course.use_latex_compiler)

def get_context(self):
"""
an override to add in specific rendering context, in this case we need to
Expand All @@ -90,7 +105,10 @@ def get_context(self):
_context = EditingDescriptor.get_context(self)
# Add some specific HTML rendering context when editing HTML modules where we pass
# the root /c4x/ url for assets. This allows client-side substitutions to occur.
_context.update({'base_asset_url': StaticContent.get_base_url_path_for_course_assets(self.location) + '/'})
_context.update({
'base_asset_url': StaticContent.get_base_url_path_for_course_assets(self.location) + '/',
'enable_latex_compiler': self.use_latex_compiler,
})
return _context

# NOTE: html descriptors are special. We do not want to parse and
Expand Down Expand Up @@ -191,6 +209,12 @@ def definition_to_xml(self, resource_fs):
elt.set("filename", relname)
return elt

@property
def non_editable_metadata_fields(self):
non_editable_fields = super(HtmlDescriptor, self).non_editable_metadata_fields
non_editable_fields.append(HtmlDescriptor.use_latex_compiler)
return non_editable_fields


class AboutFields(object):
display_name = String(
Expand Down
4 changes: 4 additions & 0 deletions common/lib/xmodule/xmodule/modulestore/inheritance.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class InheritanceMixin(XBlockMixin):
help="String customization substitutions for particular locations",
scope=Scope.settings
)
use_latex_compiler = Boolean(
help="Enable LaTeX templates?",
default=False,
scope=Scope.settings)


def compute_inherited_metadata(descriptor):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,6 @@
---
metadata:
display_name: Problem with Adaptive Hint
source_code: |
\subsection{Problem With Adaptive Hint}

% Adaptive hints are messages provided to students which depend on
% student input. These hints are produced using a script embedded
% within the problem (written in Python).
%
% Here is an example. This example uses LaTeX as a high-level
% soure language for the problem. The problem can also be coded
% directly in XML.

This problem demonstrates a question with hints, based on using the
{\tt hintfn} method.

\begin{edXscript}
def test_str(expect, ans):
print expect, ans
ans = ans.strip("'")
ans = ans.strip('"')
return expect == ans.lower()

def hint_fn(answer_ids, student_answers, new_cmap, old_cmap):
aid = answer_ids[0]
ans = str(student_answers[aid]).lower()
print 'hint_fn called, ans=', ans
hint = ''
if 'java' in ans:
hint = 'that is only good for drinking'
elif 'perl' in ans:
hint = 'not that rich'
elif 'pascal' in ans:
hint = 'that is a beatnick language'
elif 'fortran' in ans:
hint = 'those were the good days'
elif 'clu' in ans:
hint = 'you must be invariant'
if hint:
hint = "<font color='blue'>Hint: {0}</font>".format(hint)
new_cmap.set_hint_and_mode(aid,hint,'always')
\end{edXscript}

What is the best programming language that exists today? You may
enter your answer in upper or lower case, with or without quotes.

\edXabox{type="custom" cfn='test_str' expect='python' hintfn='hint_fn'}
markdown: !!null
data: |
<problem>
Expand All @@ -61,7 +16,7 @@ data: |
ans = ans.strip("'")
ans = ans.strip('"')
return expect == ans.lower()

def hint_fn(answer_ids, student_answers, new_cmap, old_cmap):
aid = answer_ids[0]
ans = str(student_answers[aid]).lower()
Expand Down
Loading