aboutsummaryrefslogtreecommitdiff
path: root/sx.el
diff options
context:
space:
mode:
authorSean Allred <code@seanallred.com>2014-12-26 17:49:11 -0500
committerSean Allred <code@seanallred.com>2014-12-26 17:50:19 -0500
commit0db8321f1dbb827666ef79bdae19b4864cb524ac (patch)
treeed8eeb818cd78d18b597839fcf25dd843b2b4677 /sx.el
parent0354bf2c974b13967558187936918db4af125571 (diff)
parenta919c72f2b58d889bf3fbdde100f9912a90c64ab (diff)
Merge branch 'master' into visit-question-from-link
Conflicts: sx.el Conflict arose from 6eb53ee0f12dd9f7d444e6749f6cc55c6db62078
Diffstat (limited to 'sx.el')
-rw-r--r--sx.el182
1 files changed, 92 insertions, 90 deletions
diff --git a/sx.el b/sx.el
index c9b5d76..c9fbf75 100644
--- a/sx.el
+++ b/sx.el
@@ -51,6 +51,96 @@
(browse-url "https://github.com/vermiculus/sx.el/issues/new"))
+;;; Site
+(defun sx--site (data)
+ "Get the site in which DATA belongs.
+DATA can be a question, answer, comment, or user (or any object
+with a `link' property).
+DATA can also be the link itself."
+ (let ((link (if (stringp data) data
+ (cdr (assoc 'link data)))))
+ (when (stringp link)
+ (replace-regexp-in-string
+ (rx line-start "http" (optional "s") "://"
+ (or
+ (sequence
+ (group-n 1 (+ (not (any "/"))))
+ ".stackexchange")
+ (group-n 2 (+ (not (any "/")))))
+ "." (+ (not (any ".")))
+ "/" (* any)
+ line-end)
+ "\\1\\2" link))))
+
+(defun sx--ensure-site (data)
+ "Add a `site' property to DATA if it doesn't have one. Return DATA.
+DATA can be a question, answer, comment, or user (or any object
+with a `link' property)."
+ (when data
+ (unless (assq 'site data)
+ (setcdr data (cons (cons 'site (sx--site data))
+ (cdr data))))
+ data))
+
+(defun sx--link-to-data (link)
+ "Convert string LINK into data that can be displayed."
+ (let ((result (list (cons 'site (sx--site link)))))
+ ;; Try to strip a question or answer ID
+ (when (or
+ ;; Answer
+ (and (or (string-match
+ ;; From 'Share' button
+ (rx "/a/"
+ ;; Question ID
+ (group (+ digit))
+ ;; User ID
+ "/" (+ digit)
+ ;; Answer ID
+ (group (or (sequence "#" (* any)) ""))
+ string-end) link)
+ (string-match
+ ;; From URL
+ (rx "/questions/" (+ digit) "/"
+ (+ (not (any "/"))) "/"
+ ;; User ID
+ (optional (group (+ digit)))
+ (optional "/")
+ (group (or (sequence "#" (* any)) ""))
+ string-end) link))
+ (push '(type . answer) result))
+ ;; Question
+ (and (or (string-match
+ ;; From 'Share' button
+ (rx "/q/"
+ ;; Question ID
+ (group (+ digit))
+ ;; User ID
+ (optional "/" (+ digit))
+ ;; Answer or Comment ID
+ (group (or (sequence "#" (* any)) ""))
+ string-end) link)
+ (string-match
+ ;; From URL
+ (rx "/questions/"
+ ;; Question ID
+ (group (+ digit))
+ "/") link))
+ (push '(type . question) result)))
+ (push (cons 'id (string-to-number (match-string-no-properties 1 link)))
+ result))
+ result))
+
+(defmacro sx-assoc-let (alist &rest body)
+ "Identical to `let-alist', except `.site' has a special meaning.
+If ALIST doesn't have a `site' property, one is created using the
+`link' property."
+ (declare (indent 1) (debug t))
+ `(progn
+ (require 'let-alist)
+ (sx--ensure-site ,alist)
+ (let-alist ,alist ,@body)))
+
+
;;; Browsing filter
(defvar sx-browse-filter
'((question.body_markdown
@@ -107,7 +197,8 @@ is intentionally skipped."
(defun sx-user-error (format-string &rest args)
"Like `user-error', but prepend FORMAT-STRING with \"[sx]\".
See `format'."
- (signal 'user-error (list (apply #'format (concat "[sx] " format) args))))
+ (signal 'user-error
+ (list (apply #'format (concat "[sx] " format-string) args))))
(defun sx-message (format-string &rest args)
"Display FORMAT-STRING as a message with ARGS.
@@ -284,95 +375,6 @@ removed from the display name before it is returned."
string))
-;;; Site
-(defun sx--site (data)
- "Get the site in which DATA belongs.
-DATA can be a question, answer, comment, or user (or any object
-with a `link' property).
-DATA can also be the link itself."
- (let ((link (if (stringp data) data
- (cdr (assoc 'link data)))))
- (when (stringp link)
- (replace-regexp-in-string
- (rx line-start "http" (optional "s") "://"
- (or
- (sequence
- (group-n 1 (+ (not (any "/"))))
- ".stackexchange")
- (group-n 2 (+ (not (any "/")))))
- "." (+ (not (any ".")))
- "/" (* any)
- line-end)
- "\\1\\2" link))))
-
-(defun sx--ensure-site (data)
- "Add a `site' property to DATA if it doesn't have one. Return DATA.
-DATA can be a question, answer, comment, or user (or any object
-with a `link' property)."
- (when data
- (unless (assq 'site data)
- (setcdr data (cons (cons 'site (sx--site data))
- (cdr data))))
- data))
-
-(defmacro sx-assoc-let (alist &rest body)
- "Identical to `let-alist', except `.site' has a special meaning.
-If ALIST doesn't have a `site' property, one is created using the
-`link' property."
- (declare (indent 1) (debug t))
- `(progn
- (require 'let-alist)
- (sx--ensure-site ,alist)
- (let-alist ,alist ,@body)))
-
-(defun sx--link-to-data (link)
- "Convert string LINK into data that can be displayed."
- (let ((result (list (cons 'site (sx--site link)))))
- ;; Try to strip a question or answer ID
- (when (or
- ;; Answer
- (and (or (string-match
- ;; From 'Share' button
- (rx "/a/"
- ;; Question ID
- (group (+ digit))
- ;; User ID
- "/" (+ digit)
- ;; Answer ID
- (group (or (sequence "#" (* any)) ""))
- string-end) link)
- (string-match
- ;; From URL
- (rx "/questions/" (+ digit) "/"
- (+ (not (any "/"))) "/"
- ;; User ID
- (optional (group (+ digit)))
- (optional "/")
- (group (or (sequence "#" (* any)) ""))
- string-end) link))
- (push '(type . answer) result))
- ;; Question
- (and (or (string-match
- ;; From 'Share' button
- (rx "/q/"
- ;; Question ID
- (group (+ digit))
- ;; User ID
- (optional "/" (+ digit))
- ;; Answer or Comment ID
- (group (or (sequence "#" (* any)) ""))
- string-end) link)
- (string-match
- ;; From URL
- (rx "/questions/"
- ;; Question ID
- (group (+ digit))
- "/") link))
- (push '(type . question) result)))
- (push (cons 'id (string-to-number (match-string-no-properties 1 link)))
- result))
- result))
-
(defcustom sx-init-hook nil
"Hook run when SX initializes.
Run after `sx-init--internal-hook'."