diff options
Diffstat (limited to 'stack-lto.el')
-rw-r--r-- | stack-lto.el | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/stack-lto.el b/stack-lto.el index 9b7ac67..776e4bb 100644 --- a/stack-lto.el +++ b/stack-lto.el @@ -27,6 +27,7 @@ ;;; Requirements (require 'stack-core) (require 'json) +(require 'shr) (defun stack-lto--question (data) "Return question DATA in a format acceptable by `org-element-interpret-data'. @@ -37,7 +38,7 @@ by the API and read by `json-read'." :tags ,(mapcar #'identity (cdr (assoc 'tags data)))) (section () (headline (:title "Question" :level 2) - ,@(stack-lto--question-answer data)) + ,(stack-lto--question-answer data)) ,@(mapcar #'stack-lto--answer (cdr (assoc 'answers data)))))) (defun stack-lto--answer (data) @@ -47,23 +48,40 @@ by the API and read by `json-read'." ;; Right now this doesn't do anything special. But it should check ;; whether the answer is accepted. How do we display that? `(headline (:title "Answer" :level 2) - ,@(stack-lto--question-answer data))) - -(defvar stack-lto-body-src-block - '(:language "markdown" :switches nil :parameters nil :hiddenp nil) - "Properties used on the src-block which represents the body.") + ,(stack-lto--question-answer data))) (defun stack-lto--question-answer (data) "Process and return the elements of DATA which questions and answers have in common." (let ((comments (mapcar #'stack-lto--comment (cdr (assoc 'comments data))))) - `(;; Body as a src block (really NOT nice). - (src-block (:value ,(stack-lto--body data) - . ,stack-lto-body-src-block)) + `(,(if stack-lto-body-src-block + ;; Body as a src block (really NOT nice). + `(src-block (:value ,(stack-lto--body data) + . ,stack-lto-body-src-block)) + ;; Body as html. Nicer... + (list 'paragraph () (stack-lto--body-rendered data))) ;; Comments as descriptive lists. If there are no comments, an ;; empty list would throw an error. ,@(when comments `((plain-list (:type descriptive) ,comments)))))) + +;;; Body rendering +(defvar stack-lto-body-src-block + '(:language "markdown" :switches nil :parameters nil :hiddenp nil) + "Properties used on the src-block which represents the body. +If this is nil, rendered html is used for the body instead.") + +(defface stack-lto-body + '((((background light)) :background "Grey90") + (((background dark)) :background "Grey10")) + "Face used on the body content of questions and answers." + :group 'stack-mode-faces) + +(defcustom stack-lto-bullet (if (char-displayable-p ?•) " •" " -") + "Bullet used on the display of html lists." + :type 'string + :group 'stack-mode) + (defun stack-lto--body (data) "Get and cleanup `body_markdown' from DATA." (concat @@ -71,6 +89,27 @@ by the API and read by `json-read'." "\r\n" "\n" (cdr (assoc 'body_markdown data))) "\n")) +;; We need to add padding in case the body contains a * at column 1 +;; (which would break org-mode). +(defvar stack-lto--padding + (propertize " " 'display " ") + "Left-padding added to each line of a body.") + +(defun stack-lto--body-rendered (data) + "Get and cleanup `body' from DATA. +Render it with `shr-render-region'." + (propertize + (with-temp-buffer + (insert (cdr (assoc 'body data))) + (let ((shr-bullet stack-lto-bullet)) + (shr-render-region (point-min) (point-max))) + (goto-char (point-min)) + (while (null (eobp)) + (insert stack-lto--padding) + (forward-line 1)) + (buffer-string)) + 'font-lock-face 'stack-lto-body)) + (defvar stack-lto-comment-item '(:bullet "- " :checkbox nil :counter nil :hiddenp nil) "Properties used on the items which represent comments.") |