aboutsummaryrefslogtreecommitdiff
path: root/stack-lto.el
diff options
context:
space:
mode:
Diffstat (limited to 'stack-lto.el')
-rw-r--r--stack-lto.el57
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.")