Skip to content

Commit

Permalink
Merge pull request #49 from trevorgunn/scriptq-function
Browse files Browse the repository at this point in the history
Add question type checked by JavaScript functions
  • Loading branch information
jverzani committed Apr 21, 2024
2 parents e3b1391 + aa76b6e commit 3a206a7
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://jverzani.github.io/QuizQuestions.jl/dev/)

A simple means to make basic web pages using Markdown with self-grading quiz questions. Question types are for numeric response, text response (graded with a regular expression), matching, a selection of one from many, or one or more from many. Can be used with Weave, Documenter, [quarto](https://quarto.org), or Pluto.
A simple means to make basic web pages using Markdown with self-grading quiz questions. Question types are for numeric response, text response (graded with a regular expression or by JavaScript function), matching, a selection of one from many, or one or more from many. Can be used with Weave, Documenter, [quarto](https://quarto.org), or Pluto.


The package creates `show` methods for mime type `text/html` for a few objects that produce HTML showing an input widget with attached javascript code to grade the input once the widget loses focus.
Expand Down
10 changes: 10 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ fillblankq(question, r"^lazy$")

----

(like `scriptq`)

```@example quiz_question
funct = "(input) => input >= 42"
scriptq(funct, label="a large number", explanation="should be at least 6 * 7")
```

----

(like `numericq`)

```@example quiz_question
Expand Down Expand Up @@ -235,6 +244,7 @@ multibuttonq
matchq
numericq
stringq
scriptq
fillblankq
hotspotq
plotlylightq
Expand Down
7 changes: 7 additions & 0 deletions examples/documenter.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ re = Regex("abc") # hide
stringq(re) # hide
```

Enter a large number

```@example quiz
funct = "(input) => input >= 42"
scriptq(funct, explanation="should be at least 6 * 7")
```

What is ``\sin(\frac{\pi}{2})``?

```@example quiz
Expand Down
8 changes: 8 additions & 0 deletions examples/quarto.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ re = Regex("abc")
stringq(re)
```

Enter a large number

```{julia}
#| echo: false
funct = "(input) => input >= 42"
scriptq(funct, explanation="should be at least 6 * 7")
```

```{julia}
#| echo: false
a = 1
Expand Down
5 changes: 5 additions & 0 deletions examples/weave.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ re = Regex("abc")
stringq(re)
```

Enter a large number

```julia; echo=false
funct = "(input) => input >= 42"
scriptq(funct, explanation="should be at least 6 * 7")
```

```julia; echo=false
a = 1
Expand Down
2 changes: 1 addition & 1 deletion src/QuizQuestions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ include("latex_show_methods.jl")
export numericq,
buttonq, radioq, booleanq, yesnoq,
multiq, multibuttonq, matchq,
stringq, fillblankq,
stringq, scriptq, fillblankq,
hotspotq, plotlylightq,
scorecard

Expand Down
9 changes: 9 additions & 0 deletions src/html_templates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ document.getElementById("{{:ID}}").addEventListener("change", function() {
});
"""

##
html_templates["function_grading_script"] = jmt"""
document.getElementById("{{:ID}}").addEventListener("change", function() {
var correct = ({{{:FUNCTION}}})(this.value);
var msgBox = document.getElementById('{{:ID}}_message');
$(grading_partial)
});
"""

##
html_templates["inputq_form"] = mt"""
</br>
Expand Down
43 changes: 43 additions & 0 deletions src/question_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,49 @@ stringq(re, label="First 3 letters...")
stringq(re::Regex; label="", hint="", explanation="", placeholder=nothing) =
Stringq(re, label, hint, explanation, placeholder)

##
mutable struct Scriptq <: Question
funct::AbstractString
label
hint
explanation
placeholder
end

"""
scriptq(funct::AbstractString, runonce::AbstractString=""; label="", hint="", explanation="", placeholder="")
Check string answer with custom script
Arguments:
* `funct`: a string representing the name of a JavaScript function/closure of signature `(str: string): boolean`
* `label`: optional label for the form element
* `hint`: optional plain-text hint that can be seen on hover
* `explanation`: text to display on a wrong selection
* `placeholder`: text shown when input widget is initially drawn
## Example
```javascript
// in JavaScript
function threshold(t) {
return (input) => input >= t;
}
```
```julia
# in Julia
stringq("threshold(42)", label="A large number")
```
"""
scriptq(funct::AbstractString; label="", hint="", explanation="", placeholder=nothing) =
Scriptq(funct, label, hint, explanation, placeholder)

##
mutable struct Numericq <: Question
Expand Down
19 changes: 19 additions & 0 deletions src/show_methods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,25 @@ function prepare_question(x::Stringq, ID)

end

function prepare_question(x::Scriptq, ID)

FORM = Mustache.render(html_templates["inputq_form"];
ID=ID,
PLACEHOLDER = isnothing(x.placeholder) ? "Text answer" : x.placeholder,
TYPE="text",
HINT = length(x.label) == 0 ? x.hint : ""
)

GRADING_SCRIPT =
Mustache.render(html_templates["function_grading_script"];
ID = ID,
FUNCTION = x.funct,
INCORRECT = "Incorrect",
CORRECT = "Correct"
)
(FORM, GRADING_SCRIPT)

end

function _make_item(i, choice, ID)
choice′ = sprint(io -> Markdown.html(io, Markdown.parse(choice)))
Expand Down

0 comments on commit 3a206a7

Please sign in to comment.