From f6b00de6b91b2f52845d33a7ccf195409ad5c9f4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 24 Jan 2015 03:06:09 -0200 Subject: Do link handling per paragraph, so we don't linkify code blocks --- sx-question-print.el | 67 +++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 32 deletions(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index 3a2eedf..c10c43e 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -357,52 +357,55 @@ E.g.: (group-n 1 (and "@" (1+ (not space)))) symbol-end) 1 font-lock-builtin-face))) - ;; Everything. + ;; Fontify. (font-lock-fontify-region (point-min) (point-max)) - ;; Compact links. - (sx-question-mode--process-links-in-buffer) - ;; And now the filling + ;; And now the content handling: (goto-char (point-min)) + ;; Handle one paragraph at a time. (while (null (eobp)) - ;; Don't fill pre blocks. + ;; Some things are not paragraphs, and shouldn't be filled. (unless (sx-question-mode--dont-fill-here) (let ((beg (point))) (skip-chars-forward "\r\n[:blank:]") (forward-paragraph) + (let ((end (point-marker))) + ;; Compact links. + (sx-question-mode--process-links beg end) + (goto-char end)) (fill-region beg (point))))) (replace-regexp-in-string "[[:blank:]]+\\'" "" (buffer-string)))) ;;; Handling links -(defun sx-question-mode--process-links-in-buffer () - "Turn all markdown links in this buffer into compact format. +(defun sx-question-mode--process-links (beg end) + "Turn all markdown links between BEG and ENG into compact format. +END must be a marker. Image links are downloaded and displayed, if `sx-question-mode-use-images' is non-nil." - (save-excursion - (goto-char (point-min)) - (while (search-forward-regexp sx-question-mode--link-regexp nil t) - ;; Tags are tag-buttons. - (let ((tag (match-string-no-properties 5))) - (if (and tag (> (length tag) 0)) - (progn (replace-match "") - (sx-tag--insert tag)) - ;; Other links are link-buttons. - (let* ((text (match-string-no-properties 1)) - (url (or (match-string-no-properties 2) - (match-string-no-properties 4) - (sx-question-mode-find-reference - (match-string-no-properties 3) - text))) - (full-text (match-string-no-properties 0))) - (when (stringp url) - (replace-match "") - (sx-question-mode--insert-link - (if (and sx-question-mode-use-images (eq ?! (elt full-text 0))) - ;; Is it an image? - (sx-question-mode--create-image url) - ;; Or a regular link - (or (if sx-question-mode-pretty-links text full-text) url)) - url)))))))) + (goto-char beg) + (while (search-forward-regexp sx-question-mode--link-regexp end t) + ;; Tags are tag-buttons. + (let ((tag (match-string-no-properties 5))) + (if (and tag (> (length tag) 0)) + (progn (replace-match "") + (sx-tag--insert tag)) + ;; Other links are link-buttons. + (let* ((text (match-string-no-properties 1)) + (url (or (match-string-no-properties 2) + (match-string-no-properties 4) + (sx-question-mode-find-reference + (match-string-no-properties 3) + text))) + (full-text (match-string-no-properties 0))) + (when (stringp url) + (replace-match "") + (sx-question-mode--insert-link + (if (and sx-question-mode-use-images (eq ?! (elt full-text 0))) + ;; Is it an image? + (sx-question-mode--create-image url) + ;; Or a regular link + (or (if sx-question-mode-pretty-links text full-text) url)) + url))))))) (defun sx-question-mode--create-image (url) "Get and create an image from URL. -- cgit v1.2.3 From 7ce3968e25c8c7a076f83f0b0d9d3b3b7d8afadc Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 24 Jan 2015 04:00:46 -0200 Subject: Handle the `code` html tag --- sx-question-print.el | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index c10c43e..5be3133 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -369,12 +369,46 @@ E.g.: (skip-chars-forward "\r\n[:blank:]") (forward-paragraph) (let ((end (point-marker))) + ;; Compact links. + (sx-question-mode--process-html-tags beg end) ;; Compact links. (sx-question-mode--process-links beg end) (goto-char end)) (fill-region beg (point))))) (replace-regexp-in-string "[[:blank:]]+\\'" "" (buffer-string)))) + +;;; HTML tags +(defconst sx-question-mode--html-tag-regexp + (rx "<" (group-n 1 "%s") (* (not (any ">"))) ">")) + +(defun sx-question-mode--process-html-tags (beg end) + "Hide all html tags between BEG and END and possibly interpret them. +END should be a marker." + ;; This code understands nested html, but not if the same tag is + ;; nested in itself (e.g., ). + (goto-char beg) + (while (search-forward-regexp + (format sx-question-mode--html-tag-regexp "[[:alpha:]]+") + end 'noerror) + (unless (save-match-data (markdown-code-at-point-p)) + (let ((tag (match-string 1)) + (l (match-beginning 0))) + (replace-match "") + (when (search-forward-regexp + (format sx-question-mode--html-tag-regexp (concat "/" tag)) + ;; Searching for a match has no bounds. + nil 'noerror) + (let ((r (copy-marker (match-beginning 0)))) + ;; The code tag is special, because it quotes everything in + ;; the middle. + (if (string= tag "quote") + (progn (replace-match "`") + (save-excursion (goto-char l) (insert "`"))) + (replace-match "") + ;; Handle stuff between the two tags. + (save-match-data (sx-question-mode--process-html-tags l r))))))))) + ;;; Handling links (defun sx-question-mode--process-links (beg end) -- cgit v1.2.3 From 6f64e45d5a957b768fb238406a64167753edd434 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 24 Jan 2015 04:05:12 -0200 Subject: Handle the `sub` and `sup` html tag --- sx-question-print.el | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index 5be3133..3b4069d 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -95,6 +95,11 @@ Some faces of this mode might be defined in the `sx-user' group." "Face used for downvoted score in the question buffer." :group 'sx-question-mode-faces) +(defface sx-question-mode-sub-sup + '((t :height 0.7)) + "Face used on and tags." + :group 'sx-question-mode-faces) + (defcustom sx-question-mode-header-tags "\nTags: " "String used before the question tags at the header." :type 'string @@ -407,7 +412,14 @@ END should be a marker." (save-excursion (goto-char l) (insert "`"))) (replace-match "") ;; Handle stuff between the two tags. - (save-match-data (sx-question-mode--process-html-tags l r))))))))) + (save-match-data (sx-question-mode--process-html-tags l r)) + (cond + ((string= tag "sub") + (add-text-properties + l r '(face sx-question-mode-sub-sup display (raise -0.3)))) + ((string= tag "sup") + (add-text-properties + l r '(face sx-question-mode-sub-sup display (raise +0.3)))))))))))) ;;; Handling links -- cgit v1.2.3 From a359f7cca7751372437b853fc648081acffc5b63 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 24 Jan 2015 04:14:27 -0200 Subject: Handle the `kbd` html tag --- sx-question-print.el | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index 3b4069d..84dbe44 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -414,6 +414,8 @@ END should be a marker." ;; Handle stuff between the two tags. (save-match-data (sx-question-mode--process-html-tags l r)) (cond + ((string= tag "kbd") + (add-text-properties l r '(face markdown-inline-code-face))) ((string= tag "sub") (add-text-properties l r '(face sx-question-mode-sub-sup display (raise -0.3)))) -- cgit v1.2.3 From 85109b7dd2ffb896151ccef2c014c7d9ea33e682 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 12 Feb 2015 14:59:46 -0200 Subject: Define possible values for answer sorting --- sx-question-print.el | 19 +++++++++++++++---- sx.el | 6 ++++++ 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index 778b580..4f50560 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -153,13 +153,24 @@ replaced with the comment." :type 'boolean :group 'sx-question-mode) +(defconst sx-question-mode--sort-methods + (let ((methods + '(("Higher-scoring" . sx-answer-higher-score-p) + ("Newer" . sx-answer-newer-p) + ("More active" . sx-answer-more-active-p)))) + (append (mapcar (lambda (x) (cons (concat (car x) " first") (cdr x))) + methods) + (mapcar (lambda (x) (cons (concat (car x) " last") + (sx--invert-predicate (cdr x)))) + methods)))) + (defcustom sx-question-mode-answer-sort-function #'sx-answer-higher-score-p "Function used to sort answers in the question buffer." - :type '(choice - (const :tag "Higher-scoring first" sx-answer-higher-score-p) - (const :tag "Newer first" sx-answer-newer-p) - (const :tag "More active first" sx-answer-more-active-p)) + :type + (cons 'choice + (mapcar (lambda (x) `(const :tag ,(car x) ,(cdr x))) + sx-question-mode--sort-methods)) :group 'sx-question-mode) diff --git a/sx.el b/sx.el index 33b36b6..381f78e 100644 --- a/sx.el +++ b/sx.el @@ -335,6 +335,12 @@ GET-FUNC and performs the actual comparison." "Return STRING with consecutive whitespace squashed together." (replace-regexp-in-string "[ \r\n]+" " " string)) +(defun sx--invert-predicate (predicate) + "Return PREDICATE function with arguments inverted. +For instance (sx--invert-predicate #'<) is the same as #'>. +Note this is not the same as negating PREDICATE." + (lambda (&rest args) (apply predicate (reverse args)))) + ;;; Printing request data (defvar sx--overlays nil -- cgit v1.2.3 From b8124d4056632ae3eb1381b19db743625a715548 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 15:58:17 -0200 Subject: Use sx-tag--format-tags --- sx-question-list.el | 2 +- sx-question-print.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sx-question-print.el') diff --git a/sx-question-list.el b/sx-question-list.el index 333fd83..6bae225 100644 --- a/sx-question-list.el +++ b/sx-question-list.el @@ -166,7 +166,7 @@ Also see `sx-question-list-refresh'." " " ;; @TODO: Make this width customizable. (Or maybe just make ;; the whole thing customizable) - (format "%-40s" (mapconcat #'sx-tag--format .tags " ")) + (format "%-40s" (sx-tag--format-tags .tags sx-question-list--site)) " " (sx-user--format "%15d %4r" .owner) (propertize " " 'display "\n"))))))) diff --git a/sx-question-print.el b/sx-question-print.el index 190c924..e535091 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -223,7 +223,7 @@ DATA can represent a question or an answer." ;; Tags (sx-question-mode--insert-header sx-question-mode-header-tags - (mapconcat #'sx-tag--format .tags " ") + (sx-tag--format-tags .tags .site_par) nil)) ;; Body (insert "\n" -- cgit v1.2.3 From 3b0008b6fc32548905510cf86ab5651e529b84ee Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Sat, 14 Feb 2015 16:02:01 -0200 Subject: Understand [meta-tag:TAG] links --- sx-question-print.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index e535091..abf3236 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -320,7 +320,8 @@ E.g.: (defconst sx-question-mode--link-regexp ;; Done at compile time. - (rx (or (and "[tag:" (group-n 5 (+ (not (any " ]")))) "]") + (rx (or (and "[" (optional (group-n 6 "meta-")) "tag:" + (group-n 5 (+ (not (any " ]")))) "]") (and "[" (group-n 1 (1+ (not (any "]")))) "]" (or (and "(" (group-n 2 (1+ (not (any ")")))) ")") (and "[" (group-n 3 (1+ (not (any "]")))) "]"))) @@ -373,7 +374,8 @@ E.g.: (let ((tag (match-string-no-properties 5))) (if (and tag (> (length tag) 0)) (progn (replace-match "") - (sx-tag--insert tag)) + ;; `match-string' 6 is the "meta-" prefix. + (sx-tag--insert tag (match-string 6))) ;; Other links are link-buttons. (let* ((text (match-string-no-properties 1)) (url (or (match-string-no-properties 2) -- cgit v1.2.3 From d4531c7a605e4d442632c7b54accbefc465a4601 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:01:27 -0200 Subject: Fix "Asked on" for answers --- sx-question-print.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index abf3236..056c265 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -63,7 +63,7 @@ Some faces of this mode might be defined in the `sx-user' group." :type 'string :group 'sx-question-mode) -(defcustom sx-question-mode-header-author-format "\nAuthor: %d %r" +(defcustom sx-question-mode-header-author-format "\nAuthor: %d %r" "String used to display the question author at the header. % constructs have special meaning here. See `sx-user--format'." :type 'string @@ -74,7 +74,7 @@ Some faces of this mode might be defined in the `sx-user' group." "Face used on the question date in the question buffer." :group 'sx-question-mode-faces) -(defcustom sx-question-mode-header-date "\nAsked on: " +(defcustom sx-question-mode-header-date "\nPosted on: " "String used before the question date at the header." :type 'string :group 'sx-question-mode) @@ -95,12 +95,12 @@ Some faces of this mode might be defined in the `sx-user' group." "Face used for downvoted score in the question buffer." :group 'sx-question-mode-faces) -(defcustom sx-question-mode-header-tags "\nTags: " +(defcustom sx-question-mode-header-tags "\nTags: " "String used before the question tags at the header." :type 'string :group 'sx-question-mode) -(defcustom sx-question-mode-header-score "\nScore: " +(defcustom sx-question-mode-header-score "\nScore: " "String used before the question score at the header." :type 'string :group 'sx-question-mode) -- cgit v1.2.3 From 3ff90f54e74d034224d70fe90bc2fc67aae6d8f4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:02:22 -0200 Subject: Improve legibility of sx-question-mode--print-section --- sx-question-print.el | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index 056c265..8ba0157 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -193,17 +193,20 @@ DATA can represent a question or an answer." 'sx-question-mode--section (if .title 1 2) 'sx-button-copy .share_link :type 'sx-question-mode-title) + ;; Sections can be hidden with overlays (sx--wrap-in-overlay '(sx-question-mode--section-content t) + ;; Author (insert (sx-user--format (propertize sx-question-mode-header-author-format 'face 'sx-question-mode-header) .owner)) + + ;; Date (sx-question-mode--insert-header - ;; Date sx-question-mode-header-date (concat (sx-time-seconds-to-date .creation_date) @@ -212,6 +215,8 @@ DATA can represent a question or an answer." (sx-time-since .last_edit_date) (sx-user--format "%d" .last_editor)))) 'sx-question-mode-date) + + ;; Score and upvoted/downvoted status. (sx-question-mode--insert-header sx-question-mode-header-score (format "%s" .score) @@ -219,6 +224,8 @@ DATA can represent a question or an answer." ((eq .upvoted t) 'sx-question-mode-score-upvoted) ((eq .downvoted t) 'sx-question-mode-score-downvoted) (t 'sx-question-mode-score))) + + ;; Tags (when .title ;; Tags (sx-question-mode--insert-header -- cgit v1.2.3 From 60df6a23b27bc1ff1dfa8f3bdd37c1c4543d980f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:08:53 -0200 Subject: Up and Down arrows when you vote --- sx-question-print.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index 8ba0157..bd764da 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -219,11 +219,11 @@ DATA can represent a question or an answer." ;; Score and upvoted/downvoted status. (sx-question-mode--insert-header sx-question-mode-header-score - (format "%s" .score) - (cond - ((eq .upvoted t) 'sx-question-mode-score-upvoted) - ((eq .downvoted t) 'sx-question-mode-score-downvoted) - (t 'sx-question-mode-score))) + (format "%s%s" .score + (cond ((eq .upvoted t) "↑") ((eq .downvoted t) "↓") (t ""))) + (cond ((eq .upvoted t) 'sx-question-mode-score-upvoted) + ((eq .downvoted t) 'sx-question-mode-score-downvoted) + (t 'sx-question-mode-score))) ;; Tags (when .title -- cgit v1.2.3 From bbc6383dea772a62c7ddc8bbcfec72e2ddd14969 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Fri, 20 Feb 2015 20:09:18 -0200 Subject: Indicate which answer is accepted --- sx-question-print.el | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'sx-question-print.el') diff --git a/sx-question-print.el b/sx-question-print.el index bd764da..62253a7 100644 --- a/sx-question-print.el +++ b/sx-question-print.el @@ -131,6 +131,16 @@ the editor's name." :type 'string :group 'sx-question-mode) +(defface sx-question-mode-accepted + '((t :foreground "ForestGreen" :inherit sx-question-mode-title)) + "Face used for accepted answers in the question buffer." + :group 'sx-question-mode-faces) + +(defcustom sx-question-mode-answer-accepted-title "Accepted Answer" + "Title used at the start of accepted \"Answer\" section." + :type 'string + :group 'sx-question-mode) + (defcustom sx-question-mode-comments-title " Comments" "Title used at the start of \"Comments\" sections." :type 'string @@ -188,10 +198,14 @@ DATA can represent a question or an answer." (insert sx-question-mode-header-title) (insert-text-button ;; Questions have title, Answers don't - (or .title sx-question-mode-answer-title) + (cond (.title) + ((eq .is_accepted t) sx-question-mode-answer-accepted-title) + (t sx-question-mode-answer-title)) ;; Section level 'sx-question-mode--section (if .title 1 2) 'sx-button-copy .share_link + 'face (if (eq .is_accepted t) 'sx-question-mode-accepted + 'sx-question-mode-title) :type 'sx-question-mode-title) ;; Sections can be hidden with overlays -- cgit v1.2.3