0

I'm trying to make the HTML form for MCQ question via org-html-export-as-html.

#+BEGIN_EXPORT html
  <form action="/save" method="POST">
#+END_EXPORT


1. What is your question

   #+NAME: field-name
   - [ ] option1
   - [ ] option2
   - [ ] option3
   - [ ] option4

#+BEGIN_EXPORT html
  <button type="submit">Submit</button>
  <button type="reset">Reset</button>
  </form>
#+END_EXPORT

I have set the (setq org-html-checkbox-type 'html) which convert each option to <input type="checkbox"> but how to add name attribute currently I'm exporting option manually.

#+BEGIN_EXPORT html
  <input requried type="checkbox" name="Q1" value="option1"/> option1 <br/>
  <input requried type="checkbox" name="Q1" value="option2"/> option2 <br/>
  <input requried type="checkbox" name="Q1" value="option3"/> option3 <br/>
  <input requried type="checkbox" name="Q1" value="option4"/> option4 <br/>
#+END_EXPORT

hackish back-end in https://gist.github.com/rhoit/a213d4574a406f094b7d881db8510bcf

2

I think the best thing to do here is make a custom exporter. Here is an example that treats checkbox items specially. Note this does not work as expected with a nested checkbox list, but I think it handles your specific example.

(setq org-html-checkbox-type 'html)
(require 'ox)
(org-export-define-derived-backend 'my-html 'html
  :translate-alist '((item . my-item-translator)))

(defun my-item-translator (item c info)
  ;; figure out what kind of item we have
  (let* ((parent (org-element-property :parent item))
     (type (org-element-property :type parent))
     (name (org-element-property :name parent))
     (value (string-trim (buffer-substring
                  (org-element-property :contents-begin item)
                  (org-element-property :contents-end item)))))

    (cond
     ;; Treat checkboxes specially
     ((org-element-property :checkbox item)
      (message "%s" item)
      (format "<input required type=%S name=\"%s\" value=\"%s\"/> %s <br/>"
              (if (string-match "radio\\'" name) "radio" "checkbox")
              name value value))
     (t
      (org-html-item item c info)))))

(browse-url (org-export-to-file 'my-html "custom.html"))

To try this code, make a new heading in the org file you want to export, and tag it with :noexport:

then put the code above in an emacs-lisp src block and run it. It should create and open a file called custom.html.

|improve this answer|||||
  • eq: Symbol’s function definition is void: org-export-define-derived-backend is guess current code is for org-mode 9.1.9. – rho Feb 3 at 15:14
  • you need to add (require 'ox). I updated the answer to include that. This solution does work on org 9+. I am not sure about earlier ones. – John Kitchin Feb 3 at 15:34
  • I added the code to init.el. After adding (require 'ox) it loads without previous error, but open the browser with blank content with html-postamble. Still trying to figure out how to export with org-html-export-to-html or with the menu C-c C-e h h. – rho Feb 3 at 15:45
  • you should remove this line (browse-url (org-export-to-file 'my-html "custom.html")) from your init file, and put it in the org file you want to export in a comment or in a section tagged :noexport:. You can run the line by putting your cursor at the end of it and typing C-x C-e. The usual C-c C-e export method will not work with this. That takes a lot more code to get working. – John Kitchin Feb 3 at 15:58
  • thanks a lot, I have been following your emacs and python stuff, never thought you will be responding one of my queries! – rho Feb 3 at 16:07
1

A different approach is to temporarily redefine one of the export functions in the usual html exporter:

(cl-letf (((symbol-function 'org-html-item)
       (lambda (item contents info)
         (let* ((plain-list (org-export-get-parent item))
            (name (org-element-property :name plain-list))
            (type (org-element-property :type plain-list))
            (counter (org-element-property :counter item))
            (checkbox (org-element-property :checkbox item))
            (tag (let ((tag (org-element-property :tag item)))
               (and tag (org-export-data tag info)))))
           (if (and checkbox name)
           (format
            "<input required type=\"checkbox\" name=\"%s\" value=\"%s\"/> %s <br/>"
            name contents contents)
         ;; The usual case
         (org-html-format-list-item
          contents type checkbox info (or tag counter)))))))

  (browse-url (org-export-to-file 'html "cl-letf.html")))

as before you put this in an emacs-lisp src block in a section tagged :noexport: and run it. The idea is to use cl-letf to temporarily redefine org-html-item which is responsible for generating the html. Here I just duplicated the code in the body of the letf statement, and added a line to capture the case for when there is a checkbox and name. If not, the usual export is done in the else clause. I find this cleaner than the answer above, but it does not work better on nested items.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.