From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jon Snader Subject: Patch to implement sorting Org tables by IP address Date: Tue, 09 Dec 2014 14:16:28 -0500 Message-ID: Mime-Version: 1.0 (Mac OS X Mail 8.1 \(1993\)) Content-Type: multipart/signed; boundary="Apple-Mail=_AF839748-3575-40AC-BFE7-A47E64889951"; protocol="application/pgp-signature"; micalg=pgp-sha1 Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:38964) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XyQHW-0002mM-7n for emacs-orgmode@gnu.org; Tue, 09 Dec 2014 14:17:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XyQHO-0002ST-OW for emacs-orgmode@gnu.org; Tue, 09 Dec 2014 14:17:10 -0500 Received: from st11p01mm-asmtpout002.mac.com ([17.172.204.237]:48027 helo=st11p01mm-asmtp002.mac.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XyQHO-0002S9-Iz for emacs-orgmode@gnu.org; Tue, 09 Dec 2014 14:17:02 -0500 Received: from [172.30.0.157] (unknown [75.115.6.171]) by st11p01mm-asmtp002.mac.com (Oracle Communications Messaging Server 7.0.5.33.0 64bit (built Aug 27 2014)) with ESMTPSA id <0NGB004JUXJVM520@st11p01mm-asmtp002.mac.com> for emacs-orgmode@gnu.org; Tue, 09 Dec 2014 19:16:45 +0000 (GMT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org --Apple-Mail=_AF839748-3575-40AC-BFE7-A47E64889951 Content-Type: multipart/mixed; boundary="Apple-Mail=_9EA150A0-CCC3-494E-B23B-714AE9BACB7E" --Apple-Mail=_9EA150A0-CCC3-494E-B23B-714AE9BACB7E Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 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=E2=80=99d like to keep sorted by IP address. The attached patch implements sorting Org tables natively. I=E2=80=99ve just completed the FSF Copyright assignment process=E2=80=94l= et me know if you need details. jcs --Apple-Mail=_9EA150A0-CCC3-494E-B23B-714AE9BACB7E Content-Disposition: attachment; filename=0001-org.el-Implement-sorting-Org-tables-by-IP-address.patch Content-Type: application/octet-stream; name="0001-org.el-Implement-sorting-Org-tables-by-IP-address.patch" Content-Transfer-Encoding: quoted-printable =46rom=20d52b9ef1fce4d4db8c948489f009805da6078817=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Jon=20Snader=20=0ADate:=20= Tue,=209=20Dec=202014=2013:31:25=20-0500=0ASubject:=20[PATCH]=20org.el:=20= Implement=20sorting=20Org=20tables=20by=20IP=20address=0A=0A*=20= lisp/org.el:=20Require=20cl-lib.=0A=20=20(org-ip-lessp):=20Implement=20= an=20IP=20address=20comparison=20function.=0A=20=20(org-do-sort):=20Add=20= dispatch=20to=20an=20IP=20sort.=20Fix=20the=20user=20prompt=0A=20=20= asking=20for=20type=20of=20sort.=0A=0A*=20lisp/org-table.el=20= (org-table-sort-lines):=20Added=20`i'=20and=20`I'=20to=20the=0A=20=20= description=20of=20options=20in=20the=20DOC=20string.=0A=0A*=20= doc/org.texi=20(org-table-sort-lines):=20Added=20the=20capability=20to=20= sort=20by=0A=20=20IP=20address=20to=20the=20documentation=20of=20= `org-table-sort-lines'.=0A=0AThese=20patches=20implement=20the=20= capability=20to=20sort=20an=20Org=20table=20by=20IP=20address.=0A---=0A=20= doc/org.texi=20=20=20=20=20=20|=2016=20++++++++--------=0A=20= lisp/org-table.el=20|=2010=20+++++-----=0A=20lisp/org.el=20=20=20=20=20=20= =20|=2025=20++++++++++++++++++++++++-=0A=203=20files=20changed,=2037=20= insertions(+),=2014=20deletions(-)=0A=0Adiff=20--git=20a/doc/org.texi=20= b/doc/org.texi=0Aindex=207b767a3..3b3c085=20100644=0A---=20= a/doc/org.texi=0A+++=20b/doc/org.texi=0A@@=20-2199,14=20+2199,14=20@@=20= below=20that=20line.=0A=20@c=0A=20@orgcmd{C-c=20^,org-table-sort-lines}=0A= =20Sort=20the=20table=20lines=20in=20the=20region.=20=20The=20position=20= of=20point=20indicates=20the=0A-column=20to=20be=20used=20for=20sorting,=20= and=20the=20range=20of=20lines=20is=20the=20range=0A-between=20the=20= nearest=20horizontal=20separator=20lines,=20or=20the=20entire=20table.=20= =20If=0A-point=20is=20before=20the=20first=20column,=20you=20will=20be=20= prompted=20for=20the=20sorting=0A-column.=20=20If=20there=20is=20an=20= active=20region,=20the=20mark=20specifies=20the=20first=20line=0A-and=20= the=20sorting=20column,=20while=20point=20should=20be=20in=20the=20last=20= line=20to=20be=0A-included=20into=20the=20sorting.=20=20The=20command=20= prompts=20for=20the=20sorting=20type=0A-(alphabetically,=20numerically,=20= or=20by=20time).=20=20When=20called=20with=20a=20prefix=0A-argument,=20= alphabetic=20sorting=20will=20be=20case-sensitive.=0A+column=20to=20be=20= used=20for=20sorting,=20and=20the=20range=20of=20lines=20is=20the=20= range=20between=0A+the=20nearest=20horizontal=20separator=20lines,=20or=20= the=20entire=20table.=20=20If=20point=20is=0A+before=20the=20first=20= column,=20you=20will=20be=20prompted=20for=20the=20sorting=20column.=20=20= If=0A+there=20is=20an=20active=20region,=20the=20mark=20specifies=20the=20= first=20line=20and=20the=20sorting=0A+column,=20while=20point=20should=20= be=20in=20the=20last=20line=20to=20be=20included=20into=20the=0A= +sorting.=20=20The=20command=20prompts=20for=20the=20sorting=20type=20= (alphabetically,=0A+numerically,=20by=20time,=20or=20by=20IP=20address).=20= =20When=20called=20with=20a=20prefix=20argument,=0A+alphabetic=20sorting=20= will=20be=20case-sensitive.=0A=20=0A=20@tsubheading{Regions}=0A=20= @orgcmd{C-c=20C-x=20M-w,org-table-copy-region}=0Adiff=20--git=20= a/lisp/org-table.el=20b/lisp/org-table.el=0Aindex=208f36d22..7e7fad4=20= 100644=0A---=20a/lisp/org-table.el=0A+++=20b/lisp/org-table.el=0A@@=20= -1656,16=20+1656,16=20@@=20specifies=20the=20first=20line=20and=20the=20= sorting=20column,=20while=20point=0A=20should=20be=20in=20the=20last=20= line=20to=20be=20included=20into=20the=20sorting.=0A=20=0A=20The=20= command=20then=20prompts=20for=20the=20sorting=20type=20which=20can=20be=0A= -alphabetically,=20numerically,=20or=20by=20time=20(as=20given=20in=20a=20= time=20stamp=0A-in=20the=20field,=20or=20as=20a=20HH:MM=20value).=20=20= Sorting=20in=20reverse=20order=20is=0A-also=20possible.=0A= +alphabetically,=20numerically,=20by=20time=20(as=20given=20in=20a=20= time=20stamp=0A+in=20the=20field,=20or=20as=20a=20HH:MM=20value),=20or=20= by=20IP=20address.=20=20Sorting=0A+in=20reverse=20order=20is=20also=20= possible.=0A=20=0A=20With=20prefix=20argument=20WITH-CASE,=20alphabetic=20= sorting=20will=20be=20case-sensitive.=0A=20=0A=20If=20SORTING-TYPE=20is=20= specified=20when=20this=20function=20is=20called=20from=20a=20Lisp=0A=20= program,=20no=20prompting=20will=20take=20place.=20=20SORTING-TYPE=20= must=20be=20a=20character,=0A-any=20of=20(?a=20?A=20?n=20?N=20?t=20?T)=20= where=20the=20capital=20letter=20indicate=20that=20sorting=0A-should=20= be=20done=20in=20reverse=20order."=0A+any=20of=20(?a=20?A=20?n=20?N=20?t=20= ?T=20?i=20?I)=20where=20the=20capital=20letter=20indicate=20that=0A= +sorting=20should=20be=20done=20in=20reverse=20order."=0A=20=20=20= (interactive=20"P")=0A=20=20=20(let*=20((thisline=20(org-current-line))=0A= =20=09=20(thiscol=20(org-table-current-column))=0Adiff=20--git=20= a/lisp/org.el=20b/lisp/org.el=0Aindex=20bed5cb9..814a229=20100755=0A---=20= a/lisp/org.el=0A+++=20b/lisp/org.el=0A@@=20-76,6=20+76,7=20@@=0A=20= (require=20'calendar)=0A=20(require=20'find-func)=0A=20(require=20= 'format-spec)=0A+(require=20'cl-lib)=0A=20=0A=20(or=20(equal=20= this-command=20'eval-buffer)=0A=20=20=20=20=20(condition-case=20nil=0A@@=20= -9051,6=20+9052,23=20@@=20When=20sorting=20is=20done,=20call=20= `org-after-sorting-entries-or-items-hook'."=0A=20=09(move-marker=20= org-clock-marker=20(point))))=0A=20=20=20=20=20(message=20"Sorting=20= entries...done")))=0A=20=0A+(defun=20org-ip-lessp=20(ip1=20ip2=20= &optional=20op)=0A+=20=20"Compare=20two=20IP=20addresses.=0A+Unless=20= the=20optional=20argument=20OP=20is=20provided,=20this=20function=20will=20= return=20T=0A+if=20IP1=20is=20less=20than=20IP2=20or=20NIL=20otherwise.=20= The=20optional=20argument=20OP=20is=0A+intended=20to=20be=20#'>=20to=20= support=20reverse=20sorting."=0A+=20=20(setq=20cmp=20(or=20op=20#'<))=0A= +=20=20(cl-labels=20((compare=20(l1=20l2)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(or=20(null=20l1)=20(null=20= l2))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(let=20((n1=20(string-to-number=20(car=20l1)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(n2=20(string-to-number=20(car=20l2))))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (cond=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20((funcall=20cmp=20n1=20n2)=20t)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((=3D=20= n1=20n2)=20(compare=20(cdr=20l1)=20(cdr=20l2)))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(t=20= nil))))))=0A+=20=20=20=20(compare=20(split-string=20ip1=20"\\.")=20= (split-string=20ip2=20"\\."))))=0A+=0A=20(defun=20org-do-sort=20(table=20= what=20&optional=20with-case=20sorting-type)=0A=20=20=20"Sort=20TABLE=20= of=20WHAT=20according=20to=20SORTING-TYPE.=0A=20The=20user=20will=20be=20= prompted=20for=20the=20SORTING-TYPE=20if=20the=20call=20to=20this=0A@@=20= -9061,7=20+9079,7=20@@=20the=20table.=0A=20If=20WITH-CASE=20is=20= non-nil,=20the=20sorting=20will=20be=20case-sensitive."=0A=20=20=20= (unless=20sorting-type=0A=20=20=20=20=20(message=0A-=20=20=20=20=20"Sort=20= %s:=20[a]lphabetic,=20[n]umeric,=20[t]ime.=20=20A/N/T=20means=20= reversed:"=0A+=20=20=20=20=20"Sort=20%s:=20[a]lphabetic,=20[n]umeric,=20= [t]ime,=20[i]p=20address.=20=20A/N/T/I=20means=20reversed:"=0A=20=20=20=20= =20=20what)=0A=20=20=20=20=20(setq=20sorting-type=20= (read-char-exclusive)))=0A=20=20=20(let=20((dcst=20(downcase=20= sorting-type))=0A@@=20-9089,6=20+9107,11=20@@=20If=20WITH-CASE=20is=20= non-nil,=20the=20sorting=20will=20be=20case-sensitive."=0A=20=09=09=20=20= =20=20=20(org-hh:mm-string-to-minutes=20x))=0A=20=09=09=20=20=20=20(t=20= 0)))=0A=20=09=20=20=20=20comparefun=20(if=20(=3D=20dcst=20sorting-type)=20= '<=20'>)))=0A+=20=20=20=20=20((=3D=20dcst=20?i)=0A+=20=20=20=20=20=20= (setq=20extractfun=20(lambda=20(x)=20(org-sort-remove-invisible=20x)))=0A= +=20=20=20=20=20=20(setq=20comparefun=20(if=20(=3D=20dcst=20= sorting-type)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20#'org-ip-lessp=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20(i1=20i2)=20= (org-ip-lessp=20i1=20i2=20#'>)))))=0A=20=20=20=20=20=20(t=20(error=20= "Invalid=20sorting=20type=20`%c'"=20sorting-type)))=0A=20=0A=20=20=20=20=20= (sort=20(mapcar=20(lambda=20(x)=20(cons=20(funcall=20extractfun=20(car=20= x))=20(cdr=20x)))=0A--=20=0A1.9.3=20(Apple=20Git-50)=0A=0A= --Apple-Mail=_9EA150A0-CCC3-494E-B23B-714AE9BACB7E-- --Apple-Mail=_AF839748-3575-40AC-BFE7-A47E64889951 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIcBAEBAgAGBQJUh0qVAAoJEO+a/ARTO0yywg8QAJG0srQSinxUPuU5njowfBud cuNOuNBwZb8MhxL2rWSQ/FeLmaNTaP8QIX51C4LZpefwq9yX1yu6lyE4Y57G3A1J ZxKnUL4IZfRPZ2ATTkbS8l0uWAbUMzN9F4MrrAhMCWNmM7JEIoVx4oRPpN6ME1X5 posap4ErnMK9uON9VB+jcyrgiHrb/SejSKBE2Cjs3gbX/KiUFvIqgAaSTckRFDAq mXcIwUMckMcDQCxrL9w41Se/F6EscK2IPyOKjZwfhX67JayqPzucDgVmVfJYSpXi cvccVHXBuJZgatZv+hZjmUBuDbdykhuEEQ5FF08Qg4BkfpmftQ3Td9qXsu2DgOuZ TQGIx85wQfh4jGDE/77bseMh1jYiRN3V9Z9mnZf2Sn0bw+1d7Nc9yVx2FTdBFoOy Y/q1wiAAd5BnnTuQLX+qxNZ3Dc3923WK9l9uq4TZRCvOKKZHwFM8tG/sqVtCoEPu 0bVum5JVUwDQSs7NRTaV8+/178hDWgsn2AG303mft1PJ7hYoemE8lvy2BJc4jXMd tPY6a4tycrvSW3/m8E0ZrJWqVePfWJFiKZ1ASvazl2DbLLUvysdJpPFIbQBbQuzs UR5UunqDlImy61Jcv/JOlFAKCgcX1sOHQg6ZD0dAoc8HERpL9gaR8LZenKuiaFHe avb0UJ0TtpNwA9CM7xYz =bgb/ -----END PGP SIGNATURE----- --Apple-Mail=_AF839748-3575-40AC-BFE7-A47E64889951--