Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit d8982c1

Browse files
committed
Bug Fix: Nested Parsing for short answer Qs
1 parent a3b3f70 commit d8982c1

3 files changed

Lines changed: 69 additions & 23 deletions

File tree

runestone/shortanswer/shortanswer.py

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,45 +13,71 @@
1313
# You should have received a copy of the GNU General Public License
1414
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
#
16-
__author__ = 'isaiahmayerchak'
17-
#acbart did most of this code, I mostly just changed the template
16+
__author__ = "isaiahmayerchak"
17+
# acbart did most of this code, I mostly just changed the template
1818

1919
from docutils import nodes
2020
from docutils.parsers.rst import directives
2121
from runestone.assess import Assessment
2222
from runestone.server.componentdb import addQuestionToDB, addHTMLToDB
2323
from runestone.common.runestonedirective import RunestoneDirective, RunestoneNode
2424

25+
2526
def setup(app):
26-
app.add_directive('shortanswer', JournalDirective)
27+
app.add_directive("shortanswer", JournalDirective)
2728
app.add_node(JournalNode, html=(visit_journal_node, depart_journal_node))
28-
app.add_autoversioned_javascript('shortanswer.js')
29-
app.add_autoversioned_javascript('timed_shortanswer.js')
30-
app.add_config_value('shortanswer_div_class', 'journal alert alert-warning', 'html')
31-
app.add_config_value('shortanswer_optional_div_class', 'journal alert alert-success', 'html')
29+
app.add_autoversioned_javascript("shortanswer.js")
30+
app.add_autoversioned_javascript("timed_shortanswer.js")
31+
app.add_config_value("shortanswer_div_class", "journal alert alert-warning", "html")
32+
app.add_config_value(
33+
"shortanswer_optional_div_class", "journal alert alert-success", "html"
34+
)
35+
3236

33-
TEXT = """
37+
TEXT_START = """
3438
<div class="runestone">
35-
<p data-component="shortanswer" class="%(divclass)s" id=%(divid)s %(optional)s>%(qnumber)s: %(content)s</p>
39+
<div data-component="shortanswer" class="%(divclass)s" id=%(divid)s %(optional)s>
40+
"""
41+
42+
TEXT_END = """
3643
</div>
44+
</div> <!-- end of runestone div -->
3745
"""
3846

47+
3948
class JournalNode(nodes.General, nodes.Element, RunestoneNode):
4049
def __init__(self, options, **kwargs):
4150
super(JournalNode, self).__init__(**kwargs)
4251
self.journalnode_components = options
4352

53+
4454
def visit_journal_node(self, node):
45-
div_id = node.journalnode_components['divid']
55+
div_id = node.journalnode_components["divid"]
4656
components = dict(node.journalnode_components)
47-
components.update({'divid': div_id})
48-
res = TEXT % components
49-
addHTMLToDB(div_id, components['basecourse'], res)
57+
components.update({"divid": div_id})
58+
59+
node.delimiter = "_start__{}_".format(node.journalnode_components["divid"])
60+
self.body.append(node.delimiter)
61+
62+
res = TEXT_START % components
5063

5164
self.body.append(res)
5265

53-
def depart_journal_node(self,node):
54-
pass
66+
67+
def depart_journal_node(self, node):
68+
69+
components = dict(node.journalnode_components)
70+
71+
res = TEXT_END % components
72+
self.body.append(res)
73+
74+
addHTMLToDB(
75+
node.journalnode_components["divid"],
76+
components["basecourse"],
77+
"".join(self.body[self.body.index(node.delimiter) + 1 :]),
78+
)
79+
80+
self.body.remove(node.delimiter)
5581

5682

5783
class JournalDirective(Assessment):
@@ -62,16 +88,17 @@ class JournalDirective(Assessment):
6288
text of the question goes here
6389
6490
65-
config values (conf.py):
91+
config values (conf.py):
6692
6793
- shortanswer_div_class - custom CSS class of the component's outermost div
6894
"""
95+
6996
required_arguments = 1 # the div id
7097
optional_arguments = 0
7198
final_argument_whitespace = True
7299
has_content = True
73100
option_spec = Assessment.option_spec.copy()
74-
option_spec.update({'optional': directives.flag})
101+
option_spec.update({"optional": directives.flag})
75102

76103
node_class = JournalNode
77104

@@ -81,15 +108,21 @@ def run(self):
81108
# Raise an error if the directive does not have contents.
82109
self.assert_has_content()
83110

84-
self.options['optional'] = 'data-optional' if 'optional' in self.options else ''
85-
self.options['content'] = "<p>".join(self.content)
111+
self.options["optional"] = "data-optional" if "optional" in self.options else ""
112+
86113
journal_node = JournalNode(self.options, rawsource=self.block_text)
87-
journal_node.source, journal_node.line = self.state_machine.get_source_and_line(self.lineno)
114+
journal_node.source, journal_node.line = self.state_machine.get_source_and_line(
115+
self.lineno
116+
)
117+
118+
self.updateContent()
119+
120+
self.state.nested_parse(self.content, self.content_offset, journal_node)
88121

89122
env = self.state.document.settings.env
90-
if self.options['optional']:
91-
self.options['divclass'] = env.config.shortanswer_optional_div_class
123+
if self.options["optional"]:
124+
self.options["divclass"] = env.config.shortanswer_optional_div_class
92125
else:
93-
self.options['divclass'] = env.config.shortanswer_div_class
126+
self.options["divclass"] = env.config.shortanswer_div_class
94127

95128
return [journal_node]
63 KB
Loading

runestone/shortanswer/test/_sources/index.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,16 @@ Short Answer
2121
:optional:
2222

2323
What are the colors in the rainbow?
24+
25+
26+
.. shortanswer:: question2
27+
:optional:
28+
29+
What are the colors in the rainbow?
30+
What is meaning of :math:`\pi r^2`
31+
How about an image?
32+
33+
.. image:: Figures/LutherBellPic.jpg
34+
:width: 200
35+
36+
This is the famous Luther Bell!

0 commit comments

Comments
 (0)