aboutsummaryrefslogtreecommitdiff
path: root/exercisesheets.el
blob: 099a7a940339f3328fcaad342dcd81f736795b7a (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
;;; 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)
  "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, default no),
`!opt' for boolean options (ask if it should be included, default yes),
`opt=' for free-form arguments for the option (include if non-empty),
`!opt=' for free-form arguments for the option (always included),
`opt=arg1,arg2,arg3' for suggestions with completion (empty means skip),
`!opt=arg1,arg2,arg3' for suggestions with completion (always included),
`opt=!arg1,arg2,arg3' for alternatives with completion (empty means skip),
`!opt=!arg1,arg2,arg3' for alternatives with completion (always included).

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

(defun Y-or-n-p (query)
  "Variant of `y-or-n-p' where return/enter means yes"
  (let ((query-replace-map 
         (append '(keymap (return . act) (enter . act)) (cdr query-replace-map))))
    (y-or-n-p query)))
    
(defun y-or-N-p (query)
  "Variant of `y-or-n-p' where return/enter means no"
  (let ((query-replace-map 
         (append '(keymap (return . skip) (enter . skip)) (cdr query-replace-map))))
    (y-or-n-p query)))

(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 specified by ARGS.

See `LaTeX-exercisesheets-read-kwopt' for the format of the strings in ARGS."
  (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" LaTeX-exercisesheets-insert-environment "oral")
     '("hint" LaTeX-exercisesheets-insert-environment "remark")
     '("hint*" LaTeX-exercisesheets-insert-environment "remark"))
    ;; 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