Adding files
This commit is contained in:
+175
-632
@@ -24,18 +24,14 @@
|
||||
(plist-get question :choices))
|
||||
|
||||
(defun linuxplus-quiz--current-question ()
|
||||
(nth linuxplus-quiz-current-question
|
||||
linuxplus-quiz-questions))
|
||||
(nth linuxplus-quiz-current-question linuxplus-quiz-questions))
|
||||
|
||||
(defun linuxplus-quiz--current-user-answer ()
|
||||
(nth linuxplus-quiz-current-question
|
||||
linuxplus-quiz-user-answers))
|
||||
(nth linuxplus-quiz-current-question linuxplus-quiz-user-answers))
|
||||
|
||||
(defun linuxplus-quiz--set-current-user-answer (answer)
|
||||
(setf
|
||||
(nth linuxplus-quiz-current-question
|
||||
linuxplus-quiz-user-answers)
|
||||
answer))
|
||||
(setf (nth linuxplus-quiz-current-question linuxplus-quiz-user-answers)
|
||||
answer))
|
||||
|
||||
(defun linuxplus-quiz--answer-marker (answer)
|
||||
(cond
|
||||
@@ -56,18 +52,14 @@
|
||||
((null answer) "unanswered")
|
||||
(t (format "%S" answer))))
|
||||
|
||||
(defun linuxplus-quiz--correct-answer-for-display
|
||||
(question)
|
||||
(let ((type
|
||||
(linuxplus-quiz--question-type question)))
|
||||
(defun linuxplus-quiz--correct-answer-for-display (question)
|
||||
(let ((type (linuxplus-quiz--question-type question)))
|
||||
(cond
|
||||
((memq type '(true-false yes-no))
|
||||
(linuxplus-quiz--answer-string
|
||||
(linuxplus-quiz--question-answer question)))
|
||||
((eq type 'multiple)
|
||||
(format "%S"
|
||||
(linuxplus-quiz--question-answers
|
||||
question)))
|
||||
(format "%S" (linuxplus-quiz--question-answers question)))
|
||||
(t "unknown"))))
|
||||
|
||||
(defun linuxplus-quiz--advance-question ()
|
||||
@@ -83,544 +75,235 @@
|
||||
(1- linuxplus-quiz-current-question))
|
||||
(setq linuxplus-quiz-current-choice 0)))
|
||||
|
||||
(defun linuxplus-quiz--multiple-selected-p
|
||||
(answer choice-index)
|
||||
(defun linuxplus-quiz--multiple-selected-p (answer choice-index)
|
||||
(and (listp answer)
|
||||
(memq choice-index answer)))
|
||||
|
||||
(defun linuxplus-quiz--toggle-current-choice ()
|
||||
(let* ((answer (copy-sequence
|
||||
(or (linuxplus-quiz--current-user-answer) nil)))
|
||||
(choice linuxplus-quiz-current-choice))
|
||||
(if (memq choice answer)
|
||||
(setq answer (delq choice answer))
|
||||
(push choice answer))
|
||||
(linuxplus-quiz--set-current-user-answer
|
||||
(sort answer #'<))))
|
||||
|
||||
(defun linuxplus-quiz--advance-choice ()
|
||||
"Advance to next multiple-choice bracket."
|
||||
(let* ((question
|
||||
(linuxplus-quiz--current-question))
|
||||
(choices
|
||||
(linuxplus-quiz--question-choices
|
||||
question)))
|
||||
"Advance to the next multiple-choice bracket if one exists."
|
||||
(let* ((question (linuxplus-quiz--current-question))
|
||||
(choices (linuxplus-quiz--question-choices question)))
|
||||
(when (and choices
|
||||
(< linuxplus-quiz-current-choice
|
||||
(1- (length choices))))
|
||||
(setq linuxplus-quiz-current-choice
|
||||
(1+ linuxplus-quiz-current-choice)))))
|
||||
|
||||
(defun linuxplus-quiz--toggle-current-choice ()
|
||||
"Toggle current multiple-choice selection."
|
||||
(let* ((answer
|
||||
(copy-sequence
|
||||
(or
|
||||
(linuxplus-quiz--current-user-answer)
|
||||
nil)))
|
||||
(choice linuxplus-quiz-current-choice)
|
||||
(was-selected
|
||||
(memq choice answer)))
|
||||
|
||||
(if was-selected
|
||||
|
||||
;; Remove selection and stay.
|
||||
(setq answer
|
||||
(delq choice answer))
|
||||
|
||||
;; Add selection and advance.
|
||||
(push choice answer)
|
||||
|
||||
(setq answer
|
||||
(sort answer #'<))
|
||||
|
||||
(linuxplus-quiz--set-current-user-answer
|
||||
answer)
|
||||
|
||||
(linuxplus-quiz--advance-choice)
|
||||
|
||||
;; Stop removal logic.
|
||||
(setq answer nil))
|
||||
|
||||
;; Removal path only.
|
||||
(when answer
|
||||
(setq answer
|
||||
(sort answer #'<))
|
||||
|
||||
(linuxplus-quiz--set-current-user-answer
|
||||
answer))))
|
||||
|
||||
(defun linuxplus-quiz--answer-correct-p
|
||||
(question user-answer)
|
||||
|
||||
(let ((type
|
||||
(linuxplus-quiz--question-type question)))
|
||||
|
||||
(defun linuxplus-quiz--answer-correct-p (question user-answer)
|
||||
(let ((type (linuxplus-quiz--question-type question)))
|
||||
(cond
|
||||
|
||||
((memq type '(true-false yes-no))
|
||||
(eq user-answer
|
||||
(linuxplus-quiz--question-answer
|
||||
question)))
|
||||
|
||||
(eq user-answer (linuxplus-quiz--question-answer question)))
|
||||
((eq type 'multiple)
|
||||
(equal
|
||||
(sort
|
||||
(copy-sequence
|
||||
(or user-answer nil))
|
||||
#'<)
|
||||
|
||||
(sort
|
||||
(copy-sequence
|
||||
(linuxplus-quiz--question-answers
|
||||
question))
|
||||
#'<)))
|
||||
|
||||
(sort (copy-sequence (or user-answer nil)) #'<)
|
||||
(sort (copy-sequence
|
||||
(linuxplus-quiz--question-answers question))
|
||||
#'<)))
|
||||
(t nil))))
|
||||
|
||||
(defun linuxplus-quiz--question-index-at-point ()
|
||||
"Return zero-based question index at point."
|
||||
(save-excursion
|
||||
(let ((found nil))
|
||||
(when
|
||||
(re-search-backward
|
||||
"^\\([0-9]+\\)\\.$"
|
||||
nil t)
|
||||
|
||||
(setq found
|
||||
(1-
|
||||
(string-to-number
|
||||
(match-string 1)))))
|
||||
|
||||
(when
|
||||
(and found
|
||||
(>= found 0)
|
||||
(< found
|
||||
(length
|
||||
linuxplus-quiz-questions)))
|
||||
(when (re-search-backward "^\\([0-9]+\\)\\.$" nil t)
|
||||
(setq found (1- (string-to-number (match-string 1)))))
|
||||
(when (and found
|
||||
(>= found 0)
|
||||
(< found (length linuxplus-quiz-questions)))
|
||||
found))))
|
||||
|
||||
(defun linuxplus-quiz--choice-index-at-point ()
|
||||
"Return zero-based multiple-choice bracket index at point."
|
||||
|
||||
(save-excursion
|
||||
|
||||
(let ((current-line
|
||||
(line-beginning-position))
|
||||
|
||||
(question-start nil)
|
||||
|
||||
(choice-index 0)
|
||||
|
||||
result)
|
||||
|
||||
;; Find question start.
|
||||
(when
|
||||
(re-search-backward
|
||||
"^\\([0-9]+\\)\\.$"
|
||||
nil t)
|
||||
|
||||
(setq question-start (point)))
|
||||
|
||||
(when question-start
|
||||
|
||||
;; Start searching after question header.
|
||||
(forward-line 1)
|
||||
|
||||
;; Walk brackets.
|
||||
(while
|
||||
(and
|
||||
(null result)
|
||||
(re-search-forward
|
||||
"\\[[^]]*\\]"
|
||||
nil t))
|
||||
|
||||
;; Did we hit current line?
|
||||
(when
|
||||
(= (line-beginning-position)
|
||||
current-line)
|
||||
|
||||
(setq result choice-index))
|
||||
|
||||
;; Next bracket index.
|
||||
(setq choice-index
|
||||
(1+ choice-index))))
|
||||
|
||||
result)))
|
||||
|
||||
(defun linuxplus-quiz--sync-current-position-from-point ()
|
||||
"Update current question and multiple-choice bracket from cursor position."
|
||||
|
||||
(let ((question-index
|
||||
(linuxplus-quiz--question-index-at-point)))
|
||||
|
||||
"Update current question from cursor position."
|
||||
(let ((question-index (linuxplus-quiz--question-index-at-point)))
|
||||
(when question-index
|
||||
|
||||
(setq linuxplus-quiz-current-question
|
||||
question-index)
|
||||
|
||||
(if
|
||||
(eq
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'multiple)
|
||||
|
||||
(setq linuxplus-quiz-current-choice
|
||||
(or
|
||||
(linuxplus-quiz--choice-index-at-point)
|
||||
0))
|
||||
|
||||
(setq linuxplus-quiz-current-question question-index)
|
||||
(unless (eq (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'multiple)
|
||||
(setq linuxplus-quiz-current-choice 0)))))
|
||||
|
||||
(defun linuxplus-quiz--invalid-input-message ()
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(let ((type
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
|
||||
(let ((type (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
(cond
|
||||
|
||||
((eq type 'true-false)
|
||||
(message
|
||||
"Valid input: t for true, f for false."))
|
||||
|
||||
(message "Valid input: t for true, f for false."))
|
||||
((eq type 'yes-no)
|
||||
(message
|
||||
"Valid input: y for yes, n for no."))
|
||||
|
||||
(message "Valid input: y for yes, n for no."))
|
||||
((eq type 'multiple)
|
||||
(message
|
||||
"Use the space bar to add/remove the * character."))
|
||||
|
||||
(message "Use the space bar to add/remove the * character."))
|
||||
(t
|
||||
(message "Invalid input.")))))
|
||||
|
||||
(defun linuxplus-quiz--set-answer-and-maybe-advance
|
||||
(answer)
|
||||
|
||||
"Set ANSWER.
|
||||
If unanswered, advance.
|
||||
If replacing, stay."
|
||||
|
||||
(defun linuxplus-quiz--set-answer-and-maybe-advance (answer)
|
||||
"Set ANSWER. If unanswered, advance; if replacing, stay."
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(let ((old-answer
|
||||
(linuxplus-quiz--current-user-answer)))
|
||||
|
||||
(linuxplus-quiz--set-current-user-answer
|
||||
answer)
|
||||
|
||||
(let ((old-answer (linuxplus-quiz--current-user-answer)))
|
||||
(linuxplus-quiz--set-current-user-answer answer)
|
||||
(unless old-answer
|
||||
(linuxplus-quiz--advance-question))
|
||||
|
||||
(linuxplus-quiz-render)))
|
||||
|
||||
(defun linuxplus-quiz-render ()
|
||||
|
||||
(let ((inhibit-read-only t))
|
||||
|
||||
(erase-buffer)
|
||||
|
||||
(insert "Linux+ Quiz\n")
|
||||
(insert "===========\n\n")
|
||||
|
||||
(let ((current-type
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
|
||||
(cond
|
||||
|
||||
((eq current-type 'true-false)
|
||||
(insert
|
||||
"Type 't' for true or 'f' for false inside the brackets.\n"))
|
||||
|
||||
(insert "Type 't' for true or 'f' for false inside the brackets.\n"))
|
||||
((eq current-type 'yes-no)
|
||||
(insert
|
||||
"Type 'y' for yes or 'n' for no inside the brackets.\n"))
|
||||
|
||||
(insert "Type 'y' for yes or 'n' for no inside the brackets.\n"))
|
||||
((eq current-type 'multiple)
|
||||
(insert
|
||||
"Use the space bar to add/remove the * character for multiple choice questions.\n"))
|
||||
|
||||
(insert "Use the space bar to add/remove the * character for multiple choice questions.\n"))
|
||||
(t
|
||||
(insert "Answer the question.\n"))))
|
||||
(insert "b = back, TAB = forward, x = finish, q = quit\n\n")
|
||||
|
||||
(insert
|
||||
"b = back, TAB = forward, x = finish, q = quit\n\n")
|
||||
|
||||
(dotimes
|
||||
(i (length linuxplus-quiz-questions))
|
||||
|
||||
(let* ((question
|
||||
(nth i linuxplus-quiz-questions))
|
||||
|
||||
(type
|
||||
(linuxplus-quiz--question-type
|
||||
question))
|
||||
|
||||
(prompt
|
||||
(linuxplus-quiz--question-prompt
|
||||
question))
|
||||
|
||||
(user-answer
|
||||
(nth i linuxplus-quiz-user-answers))
|
||||
|
||||
(current-question-p
|
||||
(= i
|
||||
linuxplus-quiz-current-question)))
|
||||
|
||||
(insert
|
||||
(format "%d.\n" (1+ i)))
|
||||
|
||||
(insert
|
||||
(format " %s\n" prompt))
|
||||
|
||||
(dotimes (i (length linuxplus-quiz-questions))
|
||||
(let* ((question (nth i linuxplus-quiz-questions))
|
||||
(type (linuxplus-quiz--question-type question))
|
||||
(prompt (linuxplus-quiz--question-prompt question))
|
||||
(user-answer (nth i linuxplus-quiz-user-answers))
|
||||
(current-question-p (= i linuxplus-quiz-current-question)))
|
||||
(insert (format "%d.\n" (1+ i)))
|
||||
(insert (format " %s\n" prompt))
|
||||
(cond
|
||||
|
||||
((eq type 'true-false)
|
||||
|
||||
(insert
|
||||
(format
|
||||
"%s %s True or False\n\n"
|
||||
|
||||
(if current-question-p
|
||||
">"
|
||||
" ")
|
||||
|
||||
(linuxplus-quiz--answer-marker
|
||||
user-answer))))
|
||||
|
||||
(format "%s %s True or False\n\n"
|
||||
(if current-question-p ">" " ")
|
||||
(linuxplus-quiz--answer-marker user-answer))))
|
||||
((eq type 'yes-no)
|
||||
|
||||
(insert
|
||||
(format
|
||||
"%s %s Yes or No\n\n"
|
||||
|
||||
(if current-question-p
|
||||
">"
|
||||
" ")
|
||||
|
||||
(linuxplus-quiz--answer-marker
|
||||
user-answer))))
|
||||
|
||||
(format "%s %s Yes or No\n\n"
|
||||
(if current-question-p ">" " ")
|
||||
(linuxplus-quiz--answer-marker user-answer))))
|
||||
((eq type 'multiple)
|
||||
|
||||
(let ((choices
|
||||
(linuxplus-quiz--question-choices
|
||||
question)))
|
||||
|
||||
(dotimes
|
||||
(choice-index
|
||||
(length choices))
|
||||
|
||||
(let*
|
||||
((selected
|
||||
(if
|
||||
(linuxplus-quiz--multiple-selected-p
|
||||
user-answer
|
||||
choice-index)
|
||||
'selected
|
||||
nil))
|
||||
|
||||
(choice-current-p
|
||||
(and
|
||||
current-question-p
|
||||
(= choice-index
|
||||
linuxplus-quiz-current-choice))))
|
||||
|
||||
(let ((choices (linuxplus-quiz--question-choices question)))
|
||||
(dotimes (choice-index (length choices))
|
||||
(let* ((selected
|
||||
(if (linuxplus-quiz--multiple-selected-p
|
||||
user-answer choice-index)
|
||||
'selected
|
||||
nil))
|
||||
(choice-current-p
|
||||
(and current-question-p
|
||||
(= choice-index linuxplus-quiz-current-choice))))
|
||||
(insert
|
||||
(format
|
||||
"%s %s %s\n"
|
||||
|
||||
(if choice-current-p
|
||||
">"
|
||||
" ")
|
||||
|
||||
(linuxplus-quiz--answer-marker
|
||||
selected)
|
||||
|
||||
(nth choice-index
|
||||
choices))))))
|
||||
|
||||
(insert "\n")))))
|
||||
|
||||
(insert
|
||||
"\nReminder: x = finish quiz, q = quit/return to lesson.\n"))
|
||||
|
||||
(format "%s %s %s\n"
|
||||
(if choice-current-p ">" " ")
|
||||
(linuxplus-quiz--answer-marker selected)
|
||||
(nth choice-index choices))))))
|
||||
(insert "\n"))))))
|
||||
(linuxplus-quiz-goto-current-answer))
|
||||
|
||||
(defun linuxplus-quiz-goto-current-answer ()
|
||||
|
||||
(goto-char (point-min))
|
||||
|
||||
(let ((target-question
|
||||
(format "^%d\\.$"
|
||||
(1+
|
||||
linuxplus-quiz-current-question))))
|
||||
|
||||
(when
|
||||
(re-search-forward
|
||||
target-question
|
||||
nil t)
|
||||
|
||||
(let ((type
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
|
||||
(1+ linuxplus-quiz-current-question))))
|
||||
(when (re-search-forward target-question nil t)
|
||||
(let ((type (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
(cond
|
||||
|
||||
((memq type '(true-false yes-no))
|
||||
|
||||
(when
|
||||
(re-search-forward
|
||||
"\\[[^]]*\\]"
|
||||
nil t)
|
||||
|
||||
(when (re-search-forward "\\[[^]]*\\]" nil t)
|
||||
(backward-char 1)))
|
||||
|
||||
((eq type 'multiple)
|
||||
|
||||
(dotimes
|
||||
(_ linuxplus-quiz-current-choice)
|
||||
|
||||
(re-search-forward
|
||||
"\\[[^]]*\\]"
|
||||
nil t))
|
||||
|
||||
(when
|
||||
(re-search-forward
|
||||
"\\[[^]]*\\]"
|
||||
nil t)
|
||||
|
||||
(dotimes (_ linuxplus-quiz-current-choice)
|
||||
(re-search-forward "\\[[^]]*\\]" nil t))
|
||||
(when (re-search-forward "\\[[^]]*\\]" nil t)
|
||||
(backward-char 1))))))))
|
||||
|
||||
(defun linuxplus-quiz-answer-true ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(if
|
||||
(eq
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'true-false)
|
||||
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance
|
||||
'true)
|
||||
|
||||
(if (eq (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'true-false)
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance 'true)
|
||||
(linuxplus-quiz--invalid-input-message)))
|
||||
|
||||
(defun linuxplus-quiz-answer-false ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(if
|
||||
(eq
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'true-false)
|
||||
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance
|
||||
'false)
|
||||
|
||||
(if (eq (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'true-false)
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance 'false)
|
||||
(linuxplus-quiz--invalid-input-message)))
|
||||
|
||||
(defun linuxplus-quiz-answer-yes ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(if
|
||||
(eq
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'yes-no)
|
||||
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance
|
||||
'yes)
|
||||
|
||||
(if (eq (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'yes-no)
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance 'yes)
|
||||
(linuxplus-quiz--invalid-input-message)))
|
||||
|
||||
(defun linuxplus-quiz-answer-no ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(if
|
||||
(eq
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'yes-no)
|
||||
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance
|
||||
'no)
|
||||
|
||||
(if (eq (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'yes-no)
|
||||
(linuxplus-quiz--set-answer-and-maybe-advance 'no)
|
||||
(linuxplus-quiz--invalid-input-message)))
|
||||
|
||||
(defun linuxplus-quiz-toggle-multiple ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(if
|
||||
(eq
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'multiple)
|
||||
|
||||
(if (eq (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))
|
||||
'multiple)
|
||||
(progn
|
||||
(linuxplus-quiz--toggle-current-choice)
|
||||
(linuxplus-quiz--advance-choice)
|
||||
(linuxplus-quiz-render))
|
||||
|
||||
(linuxplus-quiz--invalid-input-message)))
|
||||
|
||||
(defun linuxplus-quiz-next ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(let ((type
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
|
||||
(if
|
||||
(and
|
||||
(eq type 'multiple)
|
||||
|
||||
(< linuxplus-quiz-current-choice
|
||||
(1-
|
||||
(length
|
||||
(linuxplus-quiz--question-choices
|
||||
(linuxplus-quiz--current-question))))))
|
||||
|
||||
(let ((type (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
(if (and (eq type 'multiple)
|
||||
(< linuxplus-quiz-current-choice
|
||||
(1- (length
|
||||
(linuxplus-quiz--question-choices
|
||||
(linuxplus-quiz--current-question))))))
|
||||
(setq linuxplus-quiz-current-choice
|
||||
(1+
|
||||
linuxplus-quiz-current-choice))
|
||||
|
||||
(1+ linuxplus-quiz-current-choice))
|
||||
(linuxplus-quiz--advance-question)))
|
||||
|
||||
(linuxplus-quiz-render))
|
||||
|
||||
(defun linuxplus-quiz-prev ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(linuxplus-quiz--sync-current-position-from-point)
|
||||
|
||||
(let ((type
|
||||
(linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
|
||||
(if
|
||||
(and
|
||||
(eq type 'multiple)
|
||||
(> linuxplus-quiz-current-choice 0))
|
||||
|
||||
(let ((type (linuxplus-quiz--question-type
|
||||
(linuxplus-quiz--current-question))))
|
||||
(if (and (eq type 'multiple)
|
||||
(> linuxplus-quiz-current-choice 0))
|
||||
(setq linuxplus-quiz-current-choice
|
||||
(1-
|
||||
linuxplus-quiz-current-choice))
|
||||
|
||||
(1- linuxplus-quiz-current-choice))
|
||||
(linuxplus-quiz--previous-question)))
|
||||
|
||||
(linuxplus-quiz-render))
|
||||
|
||||
(defun linuxplus-quiz-invalid-key ()
|
||||
@@ -628,185 +311,71 @@ If replacing, stay."
|
||||
(linuxplus-quiz--invalid-input-message))
|
||||
|
||||
(defun linuxplus-quiz-return-to-lesson ()
|
||||
|
||||
"Return to lesson/window layout."
|
||||
|
||||
"Return to the lesson/window layout from before the quiz."
|
||||
(interactive)
|
||||
|
||||
(let ((config
|
||||
linuxplus-quiz-return-window-configuration)
|
||||
|
||||
(buffer
|
||||
linuxplus-quiz-return-buffer))
|
||||
|
||||
(when
|
||||
(window-configuration-p config)
|
||||
|
||||
(let ((config linuxplus-quiz-return-window-configuration)
|
||||
(buffer linuxplus-quiz-return-buffer))
|
||||
(when (window-configuration-p config)
|
||||
(set-window-configuration config))
|
||||
|
||||
(when
|
||||
(buffer-live-p buffer)
|
||||
|
||||
(when (buffer-live-p buffer)
|
||||
(switch-to-buffer buffer))))
|
||||
|
||||
(defun linuxplus-quiz-finish ()
|
||||
|
||||
(interactive)
|
||||
|
||||
(let ((score 0)
|
||||
|
||||
(total
|
||||
(length linuxplus-quiz-questions)))
|
||||
|
||||
(total (length linuxplus-quiz-questions)))
|
||||
(dotimes (i total)
|
||||
|
||||
(when
|
||||
(linuxplus-quiz--answer-correct-p
|
||||
(nth i linuxplus-quiz-questions)
|
||||
(nth i linuxplus-quiz-user-answers))
|
||||
|
||||
(when (linuxplus-quiz--answer-correct-p
|
||||
(nth i linuxplus-quiz-questions)
|
||||
(nth i linuxplus-quiz-user-answers))
|
||||
(setq score (1+ score))))
|
||||
|
||||
(linuxplus-record-score
|
||||
linuxplus-quiz-lesson-name
|
||||
score)
|
||||
|
||||
(linuxplus-record-score linuxplus-quiz-lesson-name score)
|
||||
(let ((inhibit-read-only t))
|
||||
|
||||
(erase-buffer)
|
||||
|
||||
(insert "Linux+ Quiz Results\n")
|
||||
(insert "===================\n\n")
|
||||
|
||||
(insert
|
||||
(format
|
||||
"Lesson: %s\n"
|
||||
linuxplus-quiz-lesson-name))
|
||||
|
||||
(insert
|
||||
(format
|
||||
"Score: %d/%d\n\n"
|
||||
score total))
|
||||
|
||||
(insert (format "Lesson: %s\n" linuxplus-quiz-lesson-name))
|
||||
(insert (format "Score: %d/%d\n\n" score total))
|
||||
(insert "Detailed review:\n\n")
|
||||
|
||||
(dotimes (i total)
|
||||
|
||||
(let*
|
||||
((question
|
||||
(nth i linuxplus-quiz-questions))
|
||||
|
||||
(prompt
|
||||
(linuxplus-quiz--question-prompt
|
||||
question))
|
||||
|
||||
(user-answer
|
||||
(nth i linuxplus-quiz-user-answers)))
|
||||
|
||||
(insert
|
||||
(format
|
||||
"%d. %s\n"
|
||||
(1+ i)
|
||||
prompt))
|
||||
|
||||
(insert
|
||||
(format
|
||||
" Your answer: %s\n"
|
||||
(linuxplus-quiz--answer-string
|
||||
user-answer)))
|
||||
|
||||
(insert
|
||||
(format
|
||||
" Correct answer: %s\n"
|
||||
(linuxplus-quiz--correct-answer-for-display
|
||||
question)))
|
||||
|
||||
(insert
|
||||
(format
|
||||
" Result: %s\n\n"
|
||||
|
||||
(if
|
||||
(linuxplus-quiz--answer-correct-p
|
||||
question
|
||||
user-answer)
|
||||
|
||||
"correct"
|
||||
|
||||
"incorrect")))))
|
||||
|
||||
(insert
|
||||
"Press q to return to the lesson.\n"))
|
||||
|
||||
(let* ((question (nth i linuxplus-quiz-questions))
|
||||
(prompt (linuxplus-quiz--question-prompt question))
|
||||
(user-answer (nth i linuxplus-quiz-user-answers)))
|
||||
(insert (format "%d. %s\n" (1+ i) prompt))
|
||||
(insert (format " Your answer: %s\n"
|
||||
(linuxplus-quiz--answer-string user-answer)))
|
||||
(insert (format " Correct answer: %s\n"
|
||||
(linuxplus-quiz--correct-answer-for-display question)))
|
||||
(insert (format " Result: %s\n\n"
|
||||
(if (linuxplus-quiz--answer-correct-p
|
||||
question user-answer)
|
||||
"correct"
|
||||
"incorrect")))))
|
||||
(insert "Press q to return to the lesson.\n"))
|
||||
(goto-char (point-min))
|
||||
|
||||
(linuxplus-quiz-mode)
|
||||
|
||||
(message
|
||||
"Quiz complete. Score: %d/%d"
|
||||
score total)))
|
||||
(message "Quiz complete. Score: %d/%d" score total)))
|
||||
|
||||
(setq linuxplus-quiz-mode-map
|
||||
|
||||
(let ((map
|
||||
(make-sparse-keymap)))
|
||||
|
||||
;; invalid printable input
|
||||
|
||||
(let ((map (make-sparse-keymap)))
|
||||
;; Invalid printable input by default.
|
||||
(dotimes (i 95)
|
||||
(define-key map
|
||||
(char-to-string (+ i 32))
|
||||
#'linuxplus-quiz-invalid-key))
|
||||
|
||||
(define-key
|
||||
map
|
||||
(char-to-string (+ i 32))
|
||||
#'linuxplus-quiz-invalid-key))
|
||||
;; Valid answers.
|
||||
(define-key map (kbd "t") #'linuxplus-quiz-answer-true)
|
||||
(define-key map (kbd "f") #'linuxplus-quiz-answer-false)
|
||||
(define-key map (kbd "y") #'linuxplus-quiz-answer-yes)
|
||||
(define-key map (kbd "n") #'linuxplus-quiz-answer-no)
|
||||
(define-key map (kbd "SPC") #'linuxplus-quiz-toggle-multiple)
|
||||
|
||||
;; valid answers
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "t")
|
||||
#'linuxplus-quiz-answer-true)
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "f")
|
||||
#'linuxplus-quiz-answer-false)
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "y")
|
||||
#'linuxplus-quiz-answer-yes)
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "n")
|
||||
#'linuxplus-quiz-answer-no)
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "SPC")
|
||||
#'linuxplus-quiz-toggle-multiple)
|
||||
|
||||
;; navigation
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "b")
|
||||
#'linuxplus-quiz-prev)
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "TAB")
|
||||
#'linuxplus-quiz-next)
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "x")
|
||||
#'linuxplus-quiz-finish)
|
||||
|
||||
(define-key
|
||||
map
|
||||
(kbd "q")
|
||||
#'linuxplus-quiz-return-to-lesson)
|
||||
;; Navigation / control.
|
||||
(define-key map (kbd "b") #'linuxplus-quiz-prev)
|
||||
(define-key map (kbd "TAB") #'linuxplus-quiz-next)
|
||||
(define-key map (kbd "x") #'linuxplus-quiz-finish)
|
||||
(define-key map (kbd "q") #'linuxplus-quiz-return-to-lesson)
|
||||
|
||||
map))
|
||||
|
||||
@@ -815,50 +384,24 @@ If replacing, stay."
|
||||
special-mode
|
||||
"LinuxPlus-Quiz"
|
||||
"Major mode for Linux+ quizzes."
|
||||
|
||||
(setq buffer-read-only t))
|
||||
|
||||
(defun linuxplus-start-quiz
|
||||
(lesson questions buffer)
|
||||
|
||||
"Start Linux+ quiz in full window."
|
||||
|
||||
(let ((return-config
|
||||
(current-window-configuration))
|
||||
|
||||
(return-buffer
|
||||
(current-buffer))
|
||||
|
||||
(buf
|
||||
(get-buffer-create buffer)))
|
||||
|
||||
(defun linuxplus-start-quiz (lesson questions buffer)
|
||||
"Start a Linux+ quiz in a full window."
|
||||
(let ((return-config (current-window-configuration))
|
||||
(return-buffer (current-buffer))
|
||||
(buf (get-buffer-create buffer)))
|
||||
(delete-other-windows)
|
||||
|
||||
(switch-to-buffer buf)
|
||||
|
||||
(linuxplus-quiz-mode)
|
||||
|
||||
(setq linuxplus-quiz-return-window-configuration
|
||||
return-config)
|
||||
|
||||
(setq linuxplus-quiz-return-buffer
|
||||
return-buffer)
|
||||
|
||||
(setq linuxplus-quiz-lesson-name
|
||||
lesson)
|
||||
|
||||
(setq linuxplus-quiz-questions
|
||||
questions)
|
||||
|
||||
(setq linuxplus-quiz-return-window-configuration return-config)
|
||||
(setq linuxplus-quiz-return-buffer return-buffer)
|
||||
(setq linuxplus-quiz-lesson-name lesson)
|
||||
(setq linuxplus-quiz-questions questions)
|
||||
(setq linuxplus-quiz-user-answers
|
||||
(make-list
|
||||
(length questions)
|
||||
nil))
|
||||
|
||||
(make-list (length questions) nil))
|
||||
(setq linuxplus-quiz-current-question 0)
|
||||
|
||||
(setq linuxplus-quiz-current-choice 0)
|
||||
|
||||
(linuxplus-quiz-render)))
|
||||
|
||||
;;; 06-linuxplus-quiz-mode.el ends here
|
||||
|
||||
Reference in New Issue
Block a user