{"action":"created","issue":{"url":"https://api.github.com/repos/edx/edx-platform/issues/6786","labels_url":"https://api.github.com/repos/edx/edx-platform/issues/6786/labels{/name}","comments_url":"https://api.github.com/repos/edx/edx-platform/issues/6786/comments","events_url":"https://api.github.com/repos/edx/edx-platform/issues/6786/events","html_url":"https://github.com/edx/edx-platform/pull/6786","id":55678121,"number":6786,"title":"Extended hint features","user":{"login":"nparlante","id":4824410,"avatar_url":"https://avatars.githubusercontent.com/u/4824410?v=3","gravatar_id":"","url":"https://api.github.com/users/nparlante","html_url":"https://github.com/nparlante","followers_url":"https://api.github.com/users/nparlante/followers","following_url":"https://api.github.com/users/nparlante/following{/other_user}","gists_url":"https://api.github.com/users/nparlante/gists{/gist_id}","starred_url":"https://api.github.com/users/nparlante/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nparlante/subscriptions","organizations_url":"https://api.github.com/users/nparlante/orgs","repos_url":"https://api.github.com/users/nparlante/repos","events_url":"https://api.github.com/users/nparlante/events{/privacy}","received_events_url":"https://api.github.com/users/nparlante/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/edx/edx-platform/labels/waiting%20on%20author","name":"waiting on author","color":"0052cc"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":80,"created_at":"2015-01-27T21:38:18Z","updated_at":"2015-05-15T18:56:16Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/6786","html_url":"https://github.com/edx/edx-platform/pull/6786","diff_url":"https://github.com/edx/edx-platform/pull/6786.diff","patch_url":"https://github.com/edx/edx-platform/pull/6786.patch"},"body":"This PR adds new \"extended hint\" features for many question types.\r\n\r\nFor example per-choice feedback..\r\n\r\n```\r\n  >>What is your favorite color?<<\r\n  () Red   {{A lot of people think it's Red, but those people are wrong.}}\r\n  () Green\r\n  (x) Blue\r\n```\r\n\r\nWhen the user tries Red as an answer, the extended hint appears.\r\nFor a sample course .tar.gz with examples of all the extended hint features see\r\n https://drive.google.com/file/d/0BzXwXoUU5YRpdVJhbUphT19Hb1E\r\n\r\nHere I will outline the implementation side of things.\r\n\r\nThe implementation has roughly three parts:\r\n-The markdown parser, adding support for {{ ... }} as above\r\n-The capa xml layer, to store and retrieve extended hints per question\r\n-Problem html generation, to show the extended hints\r\n\r\nThomas Brennan-Marquez wrote an original draft of many of these features,\r\nand I, Nick Parlante, then did some heavy revision and extension.\r\n\r\n## 1. Markdown Parsing\r\n\r\nSee edit.coffee and companion edit_spec_hint.coffee\r\n\r\nI made a high level decision to not change the old markdown\r\nparsing at all, staying quirk for quirk compatible.\r\nSo all the old tests pass unchanged. The extended hint parsing is layered on top.\r\nThe original parsing code is written in a rather functional style,\r\nso the additions are written that way too.\r\n\r\n## 2. responsetypes.py - get_extended_hints\r\n\r\nMany extended hints associate a hint with particular choices in the xml, e.g.\r\n\r\n```\r\n  <choicegroup label=\"What is your favorite color?\" type=\"MultipleChoice\">\r\n    <choice correct=\"false\">Red <choicehint>No, Blue!</choicehint> </choice>\r\n```\r\n\r\nTherefore, for each response type - multiple choice, checkbox, dropdown, text input, numeric input -\r\nthere's a get_extended_hints() method that digs the appropriate hint out of the xml\r\nand puts it in the map 'msg' to go back to the client. In some cases, there is nontrivial\r\nlogic to pick out the right extended hint depending on the specific student choices.\r\n\r\n## 3. capa_base.py - get_problem_html\r\n\r\nMany extended hints are sent to the client through the existing cmap['msg'] mechanism.\r\n\r\nThe demand hints are added in their own div in the problem.html template.\r\n\r\nAs an additional wrinkle, with the addition of extended hints, the question xml\r\noften has tags that are not just to be echoed to the user, e.g. in the <choice> above.\r\nTherefore, the get-html path needs logic to strip out these tags.\r\nPreviously, the xml was almost always just stuff to show the user, so there was nothing to remove.\r\n\r\n## 4. Other XML changes:\r\n\r\nThe PR changes additional_answer to use an attribute, as below, to be consistent with the\r\nother text-input cases. Compatibility code is provided.\r\n```\r\n  <additional_answer answer=\"Blue\"> <correcthint>hint2</correcthint> </additional_answer>\r\n```\r\n\r\nThe PR provides a longer <optioninput> xml form, as below, that also supports per-option hints.\r\nCompatibility is provided.\r\n\r\n```\r\n<optioninput>\r\n  <option correct=\"False\">dog <optionhint>No, too friendly</optionhint> </option>\r\n  <option correct=\"True\">cat</option>\r\n  <option correct=\"False\">parrot</option>\r\n</optioninput>\r\n```\r\n\r\nThe various studio question templates have been updated to show off the\r\nnew extended-hint features in markdown.\r\n\r\nAdd: With this PR, the xml has many tags, such as <demandhint> which are in the problem, but which are not supposed to be echoed in the client html. These are stripped out explicitly in get_problem_html(). Before this PR, the <additional_answer> node was kept out of the html by deleting it from the XML tree during parsing. This tag-stripping, now with many more types of tag to keep out, is now done just once in get_problem_html.\r\n"},"comment":{"url":"https://api.github.com/repos/edx/edx-platform/issues/comments/102491343","html_url":"https://github.com/edx/edx-platform/pull/6786#issuecomment-102491343","issue_url":"https://api.github.com/repos/edx/edx-platform/issues/6786","id":102491343,"user":{"login":"nparlante","id":4824410,"avatar_url":"https://avatars.githubusercontent.com/u/4824410?v=3","gravatar_id":"","url":"https://api.github.com/users/nparlante","html_url":"https://github.com/nparlante","followers_url":"https://api.github.com/users/nparlante/followers","following_url":"https://api.github.com/users/nparlante/following{/other_user}","gists_url":"https://api.github.com/users/nparlante/gists{/gist_id}","starred_url":"https://api.github.com/users/nparlante/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nparlante/subscriptions","organizations_url":"https://api.github.com/users/nparlante/orgs","repos_url":"https://api.github.com/users/nparlante/repos","events_url":"https://api.github.com/users/nparlante/events{/privacy}","received_events_url":"https://api.github.com/users/nparlante/received_events","type":"User","site_admin":false},"created_at":"2015-05-15T18:56:16Z","updated_at":"2015-05-15T18:56:16Z","body":"Alrighty, I've squashed it down and rebased it up. This includes the tracking log stuff and its testing. I need to do one jenkins/cleanup pass, as the logging entailed a lot of new code."}}