emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Patch to implement sorting Org tables by IP address
@ 2014-12-09 19:16 Jon Snader
  2014-12-12 22:58 ` Nicolas Goaziou
  0 siblings, 1 reply; 16+ messages in thread
From: Jon Snader @ 2014-12-09 19:16 UTC (permalink / raw)
  To: emacs-orgmode


[-- Attachment #1.1: Type: text/plain, Size: 501 bytes --]

There is currently no easy way to sort an Org table by IP address. The only method I could find involves selecting the IP addresses in a rectangle and piping them to sort with a complicated sort recipe. Even though I am not a system administrator, I sometimes need to maintain tables that I’d like to keep sorted by IP address.

The attached patch implements sorting Org tables natively.

I’ve just completed the FSF Copyright assignment process—let me know if you need details.

jcs



[-- Attachment #1.2: 0001-org.el-Implement-sorting-Org-tables-by-IP-address.patch --]
[-- Type: application/octet-stream, Size: 6155 bytes --]

From d52b9ef1fce4d4db8c948489f009805da6078817 Mon Sep 17 00:00:00 2001
From: Jon Snader <jcs@manfredII.local>
Date: Tue, 9 Dec 2014 13:31:25 -0500
Subject: [PATCH] org.el: Implement sorting Org tables by IP address

* lisp/org.el: Require cl-lib.
  (org-ip-lessp): Implement an IP address comparison function.
  (org-do-sort): Add dispatch to an IP sort. Fix the user prompt
  asking for type of sort.

* lisp/org-table.el (org-table-sort-lines): Added `i' and `I' to the
  description of options in the DOC string.

* doc/org.texi (org-table-sort-lines): Added the capability to sort by
  IP address to the documentation of `org-table-sort-lines'.

These patches implement the capability to sort an Org table by IP address.
---
 doc/org.texi      | 16 ++++++++--------
 lisp/org-table.el | 10 +++++-----
 lisp/org.el       | 25 ++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/doc/org.texi b/doc/org.texi
index 7b767a3..3b3c085 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -2199,14 +2199,14 @@ below that line.
 @c
 @orgcmd{C-c ^,org-table-sort-lines}
 Sort the table lines in the region.  The position of point indicates the
-column to be used for sorting, and the range of lines is the range
-between the nearest horizontal separator lines, or the entire table.  If
-point is before the first column, you will be prompted for the sorting
-column.  If there is an active region, the mark specifies the first line
-and the sorting column, while point should be in the last line to be
-included into the sorting.  The command prompts for the sorting type
-(alphabetically, numerically, or by time).  When called with a prefix
-argument, alphabetic sorting will be case-sensitive.
+column to be used for sorting, and the range of lines is the range between
+the nearest horizontal separator lines, or the entire table.  If point is
+before the first column, you will be prompted for the sorting column.  If
+there is an active region, the mark specifies the first line and the sorting
+column, while point should be in the last line to be included into the
+sorting.  The command prompts for the sorting type (alphabetically,
+numerically, by time, or by IP address).  When called with a prefix argument,
+alphabetic sorting will be case-sensitive.
 
 @tsubheading{Regions}
 @orgcmd{C-c C-x M-w,org-table-copy-region}
diff --git a/lisp/org-table.el b/lisp/org-table.el
index 8f36d22..7e7fad4 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -1656,16 +1656,16 @@ specifies the first line and the sorting column, while point
 should be in the last line to be included into the sorting.
 
 The command then prompts for the sorting type which can be
-alphabetically, numerically, or by time (as given in a time stamp
-in the field, or as a HH:MM value).  Sorting in reverse order is
-also possible.
+alphabetically, numerically, by time (as given in a time stamp
+in the field, or as a HH:MM value), or by IP address.  Sorting
+in reverse order is also possible.
 
 With prefix argument WITH-CASE, alphabetic sorting will be case-sensitive.
 
 If SORTING-TYPE is specified when this function is called from a Lisp
 program, no prompting will take place.  SORTING-TYPE must be a character,
-any of (?a ?A ?n ?N ?t ?T) where the capital letter indicate that sorting
-should be done in reverse order."
+any of (?a ?A ?n ?N ?t ?T ?i ?I) where the capital letter indicate that
+sorting should be done in reverse order."
   (interactive "P")
   (let* ((thisline (org-current-line))
 	 (thiscol (org-table-current-column))
diff --git a/lisp/org.el b/lisp/org.el
index bed5cb9..814a229 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -76,6 +76,7 @@
 (require 'calendar)
 (require 'find-func)
 (require 'format-spec)
+(require 'cl-lib)
 
 (or (equal this-command 'eval-buffer)
     (condition-case nil
@@ -9051,6 +9052,23 @@ When sorting is done, call `org-after-sorting-entries-or-items-hook'."
 	(move-marker org-clock-marker (point))))
     (message "Sorting entries...done")))
 
+(defun org-ip-lessp (ip1 ip2 &optional op)
+  "Compare two IP addresses.
+Unless the optional argument OP is provided, this function will return T
+if IP1 is less than IP2 or NIL otherwise. The optional argument OP is
+intended to be #'> to support reverse sorting."
+  (setq cmp (or op #'<))
+  (cl-labels ((compare (l1 l2)
+                       (if (or (null l1) (null l2))
+                           nil
+                         (let ((n1 (string-to-number (car l1)))
+                               (n2 (string-to-number (car l2))))
+                           (cond
+                            ((funcall cmp n1 n2) t)
+                            ((= n1 n2) (compare (cdr l1) (cdr l2)))
+                            (t nil))))))
+    (compare (split-string ip1 "\\.") (split-string ip2 "\\."))))
+
 (defun org-do-sort (table what &optional with-case sorting-type)
   "Sort TABLE of WHAT according to SORTING-TYPE.
 The user will be prompted for the SORTING-TYPE if the call to this
@@ -9061,7 +9079,7 @@ the table.
 If WITH-CASE is non-nil, the sorting will be case-sensitive."
   (unless sorting-type
     (message
-     "Sort %s: [a]lphabetic, [n]umeric, [t]ime.  A/N/T means reversed:"
+     "Sort %s: [a]lphabetic, [n]umeric, [t]ime, [i]p address.  A/N/T/I means reversed:"
      what)
     (setq sorting-type (read-char-exclusive)))
   (let ((dcst (downcase sorting-type))
@@ -9089,6 +9107,11 @@ If WITH-CASE is non-nil, the sorting will be case-sensitive."
 		     (org-hh:mm-string-to-minutes x))
 		    (t 0)))
 	    comparefun (if (= dcst sorting-type) '< '>)))
+     ((= dcst ?i)
+      (setq extractfun (lambda (x) (org-sort-remove-invisible x)))
+      (setq comparefun (if (= dcst sorting-type)
+                           #'org-ip-lessp
+                         (lambda (i1 i2) (org-ip-lessp i1 i2 #'>)))))
      (t (error "Invalid sorting type `%c'" sorting-type)))
 
     (sort (mapcar (lambda (x) (cons (funcall extractfun (car x)) (cdr x)))
-- 
1.9.3 (Apple Git-50)


[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 841 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2014-12-20 20:54 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-09 19:16 Patch to implement sorting Org tables by IP address Jon Snader
2014-12-12 22:58 ` Nicolas Goaziou
2014-12-13 14:19   ` Jon Snader
2014-12-13 14:29     ` Nicolas Goaziou
2014-12-13 15:19       ` Jon Snader
2014-12-13 16:01         ` Nicolas Goaziou
2014-12-13 18:47           ` Jon Snader
2014-12-13 22:07             ` Nicolas Goaziou
2014-12-13 22:37               ` Jon Snader
2014-12-14 11:25                 ` Nicolas Goaziou
2014-12-14 15:19                   ` Jon Snader
2014-12-14 17:18                     ` Nicolas Goaziou
2014-12-17 17:31                       ` Jon Snader
2014-12-20 11:57                         ` Nicolas Goaziou
2014-12-20 18:40                           ` Jon Snader
2014-12-20 20:55                             ` Nicolas Goaziou

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).