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

adjust for use with quarto #30

Merged
merged 1 commit into from
Jul 24, 2022
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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "QuizQuestions"
uuid = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
authors = ["jverzani <jverzani@gmail.com> and contributors"]
version = "0.3.13"
version = "0.3.14"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
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, 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), 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.
9 changes: 5 additions & 4 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# QuizQuestions

[QuizQuestions](https://github.com/jverzani/QuizQuestions.jl) allows the inclusion of self-grading quiz questions within a `Documenter`, `Weave`, or `Pluto` HTML page.
[QuizQuestions](https://github.com/jverzani/QuizQuestions.jl) allows the inclusion of self-grading quiz questions within a `Documenter`, `Weave`, [quarto](https://quarto.org), or `Pluto` HTML page.

## Basics

Expand All @@ -26,9 +26,10 @@ radioq(choices, answer; label=question, hint="A hint")

The quizzes are written in markdown with the questions in `Julia`
blocks. The above code cells would be enclosed in triple-backtick
blocks and would typically have their contents hidden from the user. How this is
done varies between `Documenter`, `Weave`, and `Pluto`. The `examples`
directory shows examples of each.
blocks and would typically have their contents hidden from the
user. How this is done varies between `Documenter`, `Weave`,
[quarto](https://quarto.org), and `Pluto`. The `examples` directory
shows examples of each.

----

Expand Down
147 changes: 147 additions & 0 deletions examples/quarto.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# A simple self-grading quiz


```{julia}
using QuizQuestions
```

Match `abc`


```{julia}
#| echo: false
re = Regex("abc")
stringq(re)
```

```{julia}
#| echo: false
a = 1
numericq(a, label= raw"What is ``\sin(\frac{\pi}{2})``?")
```

What is $100$ centimeters in meters?


```{julia}
#| echo: false
a = 1
numericq(a, units="meter(s)", hint="It is 1")
```

What is $\sqrt{2}$?


```{julia}
#| echo: false
a = sqrt(2)
Δ = 1e-2
numericq(a, Δ, hint="use 3 digits")
```

What is "one"?


```{julia}
#| echo: false
choices = ("``1``", "``2``", "``3``")
answer = 1
radioq(choices, answer, hint="select the number matching the word", keep_order=true)
```

```{julia}
#| echo: false
choices = ["beta", raw"``\beta``", "`beta`"]
answer = 2
radioq(choices, answer; label="Which is the letter?", hint="Which is the Greek symbol?")
```

Matching question


```{julia}
#| echo: false
questions = ("Select a Volvo", "Select a Mercedes", "Select an Audi")
choices = ("XC90", "A4", "GLE 350", "X1") # may be more than questions
answer = (1,3,2) # indices of correct
matchq(questions, choices, answer)
```

Button choice


```{julia}
#| echo: false
choices = ["beta", raw"``\beta``", "`beta`"]
answer = 2
buttonq(choices, answer; label="choose the letter", hint="Which is the Greek symbol?")
```

Hotspot


```{julia}
#| hold: true
#| echo: false
using Plots
p1 = plot(x -> x^2, axis=nothing, legend=false)
p2 = plot(x -> x^3, axis=nothing, legend=false)
p3 = plot(x -> -x^2, axis=nothing, legend=false)
p4 = plot(x -> -x^3, axis=nothing, legend=false)
l = @layout [a b; c d]
p = plot(p1, p2, p3, p4, layout=l)
imgfile = tempname() * ".png"
savefig(p, imgfile)
hotspotq(imgfile, (0,1/2), (0, 1/2), label="What best matches the graph of ``f(x) = -x^4``?")
```


yesnoq

```{julia}
#| echo: false
yesnoq("yes"; label="Having fun?", hint="It isn't so hard", explanation="We want you to be having fun")
```

booleanq

```{julia}
#| echo: false
booleanq(true; label="Having fun?", hint="It isn't so hard", explanation="We want you to be having fun")
```

multiq

```{julia}
#| echo: false
choices = ["pear", "tomato", "banana"]
answers = [1,3]
multiq(choices, answers; label="yellow foods", hint="not the red one!")
```

multibuttonq

```{julia}
#| echo: false
choices = ["pear", "tomato", "banana"]
answers = [1,3]
multibuttonq(choices, answers; label="yellow foods", hint="not the red one!")
```

fillblankq

```{julia}
#| echo: false
question = "The quick brown fox jumped over the ____ dog"
fillblankq(question, r"lazy")
```

```{julia}
#| echo: false
fillblankq(question, ("lazy", "brown", "sleeping"), 1)
```

```{julia}
#| echo: false
fillblankq("____ ``+ 2 = 4``", 2)
```
50 changes: 29 additions & 21 deletions src/html_templates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ html_templates["question_tpl"] = mt"""
<form class="mx-2 my-3" name='WeaveQuestion' data-id='{{:ID}}' data-controltype='{{:TYPE}}'>
<div class='form-group {{:STATUS}}'>
<div class='controls'>
<div class="form-floating input-group" id="controls_{{:ID}}">
{{#:LABEL}}
<label for="controls_{{:ID}}">{{{:LABEL}}}{{#:HINT}}<span href="#" title='{{{:HINT}}}'>&nbsp;🎁</span>{{/:HINT}}
<label for="controls_{{:ID}}">{{{:LABEL}}}{{#:HINT}}<span href="#" title="{{{:HINT}}}">&nbsp;🎁</span>{{/:HINT}}
</label>
{{/:LABEL}}
<div class="form" id="controls_{{:ID}}">
<div style="padding-top: 5px">
{{{:FORM}}}
{{^:LABEL}}{{#:HINT}}<label for="controls_{{:ID}}"><span href="#" title='{{{:HINT}}}'>&nbsp;🎁</span></label>{{/:HINT}}{{/:LABEL}}
{{^:LABEL}}{{#:HINT}}<label for="controls_{{:ID}}"><span href="#" title="{{{:HINT}}}">&nbsp;🎁</span></label>{{/:HINT}}{{/:LABEL}}
</div>
</div>
<div id='{{:ID}}_message' style="padding-bottom: 15px"></div>
Expand All @@ -59,28 +59,33 @@ document.getElementById("{{:ID}}").addEventListener("change", function() {

##
html_templates["inputq_form"] = mt"""
<div class="row">
<span style="width:90%">
</br>
<div class="input-group">
<input id="{{:ID}}" type="{{:TYPE}}" class="form-control" placeholder="{{:PLACEHOLDER}}">
</span>
<span style="width:10%">{{#:UNITS}}{{{:UNITS}}}{{/:UNITS}}{{#:HINT}}<span href="#" title='{{{:HINT}}}'>&nbsp;🎁</span>{{/:HINT}}
</span>
{{#:UNITS}}
<span class="input-group-append">&nbsp;{{{:UNITS}}}&nbsp;</span>
{{/:UNITS}}
{{#:HINT}}
<span class="input-group-append" href="#" title="{{{:HINT}}}">&nbsp;🎁</span>
{{/:HINT}}
</div>
"""


## Multiple choice (one of many)
## XXX add {{INLINE}}
## We do *not* use sibling elements, as suggested by Bootstrap here
html_templates["Radioq"] = mt"""
{{#:ITEMS}}
<div class="form-check">
<label>
<input class="form-check-input" type="radio" name="radio_{{:ID}}"
<label class="form-check-label" for="radio_{{:ID}}_{{:VALUE}}">
<input class="form-check-input" type="radio" name="radio_{{:ID}}"
id="radio_{{:ID}}_{{:VALUE}}" value="{{:VALUE}}">
<span class="label-body">
</input>
<span class="label-body px-1">
{{{:LABEL}}}
</span>
</input>
</label>
</label>
</div>
{{/:ITEMS}}
"""
Expand All @@ -96,9 +101,9 @@ rb.addEventListener("change", function() {
## ----

html_templates["Buttonq"] = mt"""
<div id="buttongroup_{{:ID}}" class="btn-group">
<div id="buttongroup_{{:ID}}" class="btn-group-vertical">
{{#:BUTTONS}}
<button class="toggle-btn" aria-pressed="false" id="button_{{:ID}}_{{:i}}" value="{{:ANSWER}}" style="width:100%;text-align:left; padding-left:10px; {{#:BLUE}}background:{{{:BLUE}}}{{/:BLUE}}" onclick="return false;">
<button type="button" class="btn toggle-btn px-4 my-1 btn-light active" aria-pressed="false" id="button_{{:ID}}_{{:i}}" value="{{:ANSWER}}" style="width:100%;text-align:left; padding-left:10px; {{#:BLUE}}background:{{{:BLUE}}}{{/:BLUE}}" onclick="return false;">
{{{:TEXT}}
</button>
{{/:BUTTONS}}
Expand Down Expand Up @@ -171,18 +176,21 @@ rb.addEventListener("change", function() {
"""

html_templates["MultiButtonq"] = mt"""
<div id="buttongroup_{{:ID}}" class="btn-group">
<div id="buttongroup_{{:ID}}" class="btn-group-vertical">
{{#:BUTTONS}}
<button class="toggle-btn" aria-pressed="false" id="button_{{:ID}}_{{:i}}" name="{{:i}}" value="unclicked" style="width:100%;text-align:left; padding-left:10px; {{#:BLUE}}background:{{{:BLUE}}}{{/:BLUE}}" onclick="return false;">
<button type="button" class="btn toggle-btn px-4 my-1 btn-light active" aria-pressed="false"
id="button_{{:ID}}_{{:i}}" name="{{:i}}" value="unclicked"
style="width:100%;text-align:left; padding-left:10px; {{#:BLUE}}background:{{{:BLUE}}}{{/:BLUE}}" onclick="return false;">
{{{:TEXT}}
</button>
{{/:BUTTONS}}

<button id="button_{{:ID}}-done"
<div class="row mt-1">
<button id="button_{{:ID}}-done" class="btn btn-primary"
style="display:block; margin:auto;text-align:center;{{#:BLUE}}background:{{{:BLUE}}}{{/:BLUE}}" onclick="return false;">
DONE
</button>

</div>
</div>

"""

Expand Down Expand Up @@ -295,7 +303,7 @@ html_templates["fill_in_blank_select"] = """
"""

html_templates["fill_in_blank_input"] = """
<input id="{{:ID}}" type="{{:TYPE}}" class="form-control" placeholder="{{:PLACEHOLDER}}">
<input id="{{:ID}}" type="{{:TYPE}}" class="form-{{^:INLINE}}control{{/:INLINE}}" placeholder="{{:PLACEHOLDER}}">
"""

## -------
Expand Down
4 changes: 2 additions & 2 deletions src/question_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Arguments:
```
choices = ["pear", "tomato", "banana"]
answers = [1,3]
multiplecq(choices, answers; label="yellow foods", hint="not the red one!")
multiq(choices, answers; label="yellow foods", hint="not the red one!")
```

"""
Expand Down Expand Up @@ -592,7 +592,7 @@ plotlylightq(p; label=question, correct_answer=correct_answer)
```

!!! note
The use of `PlotlyLight` graphics works with `Weave` and `Pluto`, but is unusable from `Documenter`.
The use of `PlotlyLight` graphics works with `Weave` and `Pluto`, but is unusable from `quarto` and `Documenter`.

"""
function plotlylightq(p, xs=(-Inf, Inf), ys=(-Inf,Inf);
Expand Down
2 changes: 2 additions & 0 deletions src/show_methods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ function blank(x::FillBlankStringQ, ID)
BLANK = Mustache.render(html_templates["fill_in_blank_input"],
ID = ID,
TYPE="text",
INLINE=true,
PLACEHOLDER=PLACEHOLDER)

GRADING_SCRIPT =
Expand All @@ -242,6 +243,7 @@ function blank(x::FillBlankNumericQ, ID)
BLANK = Mustache.render(html_templates["fill_in_blank_input"],
ID = ID,
TYPE="number",
INLINE=true,
PLACEHOLDER=PLACEHOLDER)
GRADING_SCRIPT =
Mustache.render(html_templates["input_grading_script"];
Expand Down