## A function to save an org-file for submitting assignments in org-mode

| categories: org-mode | tags: | View Comments

I am going to be assigning homeworks and quizzes in org-mode next semester, and it would be nice if there was a function that would save the file with the right name in the right place. The file will have some keywords at the top to identify the student, course and assignment. Those look like:

#+NAME: John Kitchin
#+ANDREWID: jkitchin
#+COURSE: 06-640
#+ASSIGNMENT: quiz1


I would like a function that saves the current buffer to a file like /some-path/ANDREWID-COURSE-ASSIGNMENT.org. That will be "turning the assignment in" so I can do some analysis of the files. I previously wrote about getting keywords from org-files here . We will build on that to accomplish this goal. Here is the function that seems to do what I want. For now it saves the file in the same directory, with the correct name.

(defun submit-assignment ()
"Save current buffer to assignment. You must set #+ANDREWID, #+COURSE and #+ASSIGNMENT. There is no checking for this."
(interactive)
(save-buffer)
(let ((org-keywords (org-element-map (org-element-parse-buffer 'element) 'keyword
(lambda (keyword) (cons (org-element-property :key keyword)
(org-element-property :value keyword)))))
(assignment-content (buffer-string)) ; store contents to write to file later
(assignment-filename))
;; create the filename we will save the buffer in
(setq assignment-filename (concat (cdr (assoc "ANDREWID" org-keywords))
"-"
(cdr (assoc "COURSE" org-keywords))
"-"
(cdr (assoc "ASSIGNMENT" org-keywords))
".org"))
;; now write out contents to filename
(with-temp-file assignment-filename
(insert assignment-content))
(message "%s was submitted" assignment-filename)))

(submit-assignment)

jkitchin-06-640-quiz1.org was submitted


Now, we have a nice function that can be put as a link in the org-file:

elisp:submit-assignment
, or
elisp:submit-assignment
. The assignment will be copied to a location specified, and I can grade it, assess it, etc… from there. That function will have to be loaded by students, but since I provide them with lisp files that are loaded at startup that should not be an issue.

This solution lacks some features I have to think about. For example, if the path where everyone submits to is common, everyone will be able to read the file, which is not desirable. It is also not feasible to make the submitted files read-only to the students this way (so they cannot modify the files after they turn them in). I could have the submit function do something like submit to box.com by email.

I am not sure how grading of these files would go. In the past, I have preferred PDF files (which you can export org to) because I could grade them using a tablet without modifying the actual content in the files. However it would not be simple at all to export an org-file to PDF with that data in a machine readable way. One point of having them in org-mode is that I could collect statistics from the headings of many files pretty easily. I have written code to annotate org-files in the past, which I might have to dig out.

There is a limitation of the submit function, and that is if the org-file references images or other files (I would expect many of my assignments would have plots in them). Those would not be copied to the right place. I handle those when I publish the blog, so it could be done. But, it would require creating a new directory, and writing all the files to it (including making sure the relative paths are handled correctly), or creating some kind of zip-archive that contains everything. That sounds like a project for another day!

TODO rewrite the submit-assignment function to copy any images or files it links to into the submission directory
nil