aboutsummaryrefslogtreecommitdiff
path: root/exercisesheets.el
blob: 6c3774785dc095e0213c4070a06e209a9bd01721 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
;;; exercisesheets.el --- AUCTeX style for `exercisesheets.sty'

;; Author: Sebastian Kuhnert <mail@sebastian-kuhnert.de>
;; Created: 2009-11-18
;; Keywords: tex


(defun LaTeX-exercisesheets-read-kwopt (context spec &optional required)
  "Ask the user if/how an option should be included.

CONTEXT is used in the prompt.

SPEC is a string of the form `opt' for boolean options (ask if it should be included),
`opt=' for free-form arguments for the option (include if non-empty),
`opt=arg1,arg2,arg3' for suggestions with completion (empty means skip),
`opt=!arg1,arg2,arg3' for alternatives with completion (empty means skip).

If REQUIRED is non-nil, 

The result is the string to be used as argument. If the option is skipped, the result is nil."
  (if (string-match "^\\(.*\\)=\\(!?\\)\\(.*\\)$" spec)
      (let* ((optstr (if required "optional " ""))
             (require-match (if (match-string 2 spec) t nil))
             (answer (save-match-data 
                       (if (string= "" (match-string 3 spec))
                           (read-string (concat context ": " optstr "argument " (match-string 1 spec) "="))
                         (completing-read (concat context ": " optstr "argument " (match-string 1 spec) "=")
                                          (split-string (match-string 3 spec) ",")
                                          nil
                                          require-match)))))
        (if (or (not (string= "" answer)) required)
            (if (string-match-p "[,= ]" answer)
                (concat (match-string 1 spec) "={" answer "}")
              (concat (match-string 1 spec) "=" answer))
          nil))
    (if (y-or-n-p (concat context ": include argument " spec "? "))
        spec
      nil)))

(defun LaTeX-exercisesheets-read-kwopts(context startdelim enddelim &rest specs)
  (let* ((anslist (mapcar
                   (lambda (spec) (LaTeX-exercisesheets-read-kwopt context spec))
                   args))
         (ansstr  (list-to-string (delq nil anslist) ",")))
    (if (not (string= "" ansstr))
        (concat startdelim ansstr enddelim))))

(defun LaTeX-exercisesheets-insert-kwopts(optional &rest specs)
  (if optional
      (LaTeX-exercisesheets-read-kwopts(nil "[" "]" specs))
    (LaTeX-exercisesheets-read-kwopts(nil "{" "}" specs))))

(defun LaTeX-exercisesheets-insert-environment (env &rest args)
  "Insert environment ENV considering keyword arguments ARGS.

Each entry of ARGS can be a string (a keyword) or a conscell
consisting of keyword and explanation for the user (used in the prompt)."
  (LaTeX-insert-environment env (LaTeX-exercisesheets-read-kwopts (concat env " environment") "[" "]" args)))

(TeX-add-style-hook "exercisesheets"
  (lambda ()
    ;; New symbols
    (TeX-add-symbols
     '("subject" 1)
     '("TODO" 0)
     '("points" [ (LaTeX-exercisesheets-insert-kwopts "optional" "bonus") ] "points")
     '("exshset" 1)
     '("ifsolutions" 2))
    ;; New environments
    (LaTeX-add-environments
     '("sheet" LaTeX-exercisesheets-insert-environment "date=" "note=" "title=")
     '("exercise" LaTeX-exercisesheets-insert-environment "points=" "oral" "name=" "firstline=")
     "solution" ;;; oral
     "hint"  
     "hint*")
    ;; Warning keywords
    (font-latex-add-keywords '("TODO")
                             'warning)
    ))

(defvar LaTeX-exercisesheets-package-options '("only=" "all" "solutions" "solutions=oral" "solutionsby=" "language=")
  "Package options for the exercisesheets package.")

;;; exercisesheets.el ends here