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

Commit b160087

Browse files
committed
🚧 Adding horizontal parsons
1 parent 81015a2 commit b160087

22 files changed

Lines changed: 4103 additions & 1136 deletions

package-lock.json

Lines changed: 3497 additions & 209 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"build": "webpack --mode=development",
1010
"buildj": "webpack --mode=development --profile --json > stats.json",
1111
"watch": "webpack --mode=development --watch",
12+
"start": "webpack-dev-server --mode=development --open",
1213
"serve": "cd dist; python -m http.server 8080; cd ..",
1314
"dist": "webpack --mode=production",
1415
"distj": "webpack --mode=production --profile --json > stats.json",
@@ -18,16 +19,17 @@
1819
"author": "",
1920
"license": "ISC",
2021
"devDependencies": {
21-
"copy-webpack-plugin": "^9.0.0",
2222
"compression-webpack-plugin": "^9.0.0",
23+
"copy-webpack-plugin": "^9.0.0",
2324
"css-loader": "^6.0.0",
2425
"css-minimizer-webpack-plugin": "^3.0.0",
2526
"html-loader": "^3.0.0",
2627
"html-webpack-plugin": "^5.0.0",
2728
"mini-css-extract-plugin": "^2.0.0",
2829
"webpack": "^5.61.0",
2930
"webpack-bundle-analyzer": "^4.0.0",
30-
"webpack-cli": "^4.0.0"
31+
"webpack-cli": "^4.9.2",
32+
"webpack-dev-server": "^4.7.4"
3133
},
3234
"dependencies": {
3335
"-": "0.0.1",
@@ -41,4 +43,4 @@
4143
"vega-embed": "3.14.0",
4244
"wavedrom": "^2.0.0"
4345
}
44-
}
46+
}

runestone/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from .dragndrop import DragNDrop
1414
from .fitb import FillInTheBlank
1515
from .groupsub import GroupSubmission
16+
from .hparsons import HParsonsNode
1617
from .khanex import Khanex
1718
from .selectquestion import SelectQuestion
1819
from .matrixeq import MatrixEq
@@ -246,6 +247,7 @@ def build(options):
246247
"disqus": DisqusDirective,
247248
"dragndrop": DragNDrop,
248249
"groupsub": GroupSubmission,
250+
"hparsons": HParsonsNode,
249251
"parsonsprob": ParsonsProblem,
250252
"poll": Poll,
251253
"quizly": Quizly,

runestone/hparsons/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .shortanswer import *
1+
from .hparsons import *

runestone/hparsons/css/hparsons.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
div.journal div.latexoutput {
1+
div.hparsons div.latexoutput {
22
background-color: #eeeeee;
33
padding: 1em;
44
margin-bottom: 10px;

runestone/hparsons/css/shortanswer.css

Lines changed: 0 additions & 6 deletions
This file was deleted.

runestone/hparsons/hparsons.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Copyright (C) 2011 Bradley N. Miller
2+
#
3+
# This program is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
#
16+
__author__ = "ziwu"
17+
18+
from docutils import nodes
19+
from docutils.parsers.rst import directives
20+
from runestone.mchoice import Assessment
21+
from runestone.server.componentdb import (
22+
addQuestionToDB,
23+
addHTMLToDB,
24+
maybeAddToAssignment,
25+
)
26+
from runestone.common.runestonedirective import RunestoneDirective, RunestoneIdNode
27+
28+
29+
def setup(app):
30+
app.add_directive("hparsons", HParsonsDirective)
31+
# adding the html
32+
app.add_node(HParsonsNode, html=(visit_hparsons_node, depart_hparsons_node))
33+
# TODO: figure out what these means
34+
# app.add_config_value("shortanswer_div_class", "journal alert alert-warning", "html")
35+
# app.add_config_value(
36+
# "shortanswer_optional_div_class", "journal alert alert-success", "html"
37+
# )
38+
39+
40+
# TODO: what is the alert and alert-warnings?
41+
TEMPLATE_START = """
42+
<div style="max-width: none;">
43+
<div data-component="hparsons" id="%(divid)s" data-question_label="%(question_label)s" class="alert alert-warning hparsons" >
44+
<div class="hparsons_question hparsons-text" >
45+
"""
46+
47+
TEMPLATE_END = """
48+
</div>
49+
<div class="hparsons">
50+
</div>
51+
</div>
52+
</div>
53+
"""
54+
55+
56+
# seems to be the same for all
57+
class HParsonsNode(nodes.General, nodes.Element, RunestoneIdNode):
58+
def __init__(self, options, **kwargs):
59+
super(HParsonsNode, self).__init__(**kwargs)
60+
self.runestone_options = options
61+
62+
# generate the first part of the html
63+
def visit_hparsons_node(self, node):
64+
div_id = node.runestone_options["divid"]
65+
components = dict(node.runestone_options)
66+
components.update({"divid": div_id})
67+
node.delimiter = "_start__{}_".format(node.runestone_options["divid"])
68+
self.body.append(node.delimiter)
69+
res = TEMPLATE_START % components
70+
self.body.append(res)
71+
72+
73+
# generate the second part of the html
74+
def depart_hparsons_node(self, node):
75+
components = dict(node.runestone_options)
76+
res = TEMPLATE_END % components
77+
self.body.append(res)
78+
addHTMLToDB(
79+
node.runestone_options["divid"],
80+
components["basecourse"],
81+
"".join(self.body[self.body.index(node.delimiter) + 1 :]),
82+
)
83+
self.body.remove(node.delimiter)
84+
85+
86+
class HParsonsDirective(Assessment):
87+
"""
88+
.. hparsons:: uniqueid
89+
90+
nothing makes sense at all.
91+
92+
"""
93+
94+
required_arguments = 0 # the div id
95+
optional_arguments = 0
96+
final_argument_whitespace = True
97+
has_content = False
98+
option_spec = Assessment.option_spec.copy()
99+
# seem to be defining the type of the options
100+
# option_spec.update({"mathjax": directives.flag})
101+
102+
# just fill it with the name
103+
node_class = HParsonsNode
104+
105+
def run(self):
106+
# same
107+
super(HParsonsDirective, self).run()
108+
addQuestionToDB(self)
109+
# Raise an error if the directive does not have contents.
110+
self.assert_has_content()
111+
112+
# specifying default for option?
113+
# TODO: ignoring for now
114+
# self.options["mathjax"] = "data-mathjax" if "mathjax" in self.options else ""
115+
116+
# same
117+
hparsons_node = HParsonsNode(self.options, rawsource=self.block_text)
118+
hparsons_node.source, hparsons_node.line = self.state_machine.get_source_and_line(
119+
self.lineno
120+
)
121+
122+
# exist in short answer and mchoice but not parsons
123+
# For MChoice its better to insert the qnum into the content before further processing.
124+
self.updateContent()
125+
126+
# same as mchoice, different from parsons. i think it is for generating instructions.
127+
self.state.nested_parse(self.content, self.content_offset, hparsons_node)
128+
# parsons:
129+
# self.state.nested_parse(
130+
# self.options["instructions"], self.content_offset, parsons_node
131+
# )
132+
133+
# adding classes outside of the div based on the options
134+
env = self.state.document.settings.env
135+
if self.options["optional"]:
136+
self.options["divclass"] = env.config.shortanswer_optional_div_class
137+
else:
138+
self.options["divclass"] = env.config.shortanswer_div_class
139+
140+
# same
141+
maybeAddToAssignment(self)
142+
143+
# same
144+
return [hparsons_node]

0 commit comments

Comments
 (0)