[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Expanding list into string within a command
From: |
Jean Louis |
Subject: |
Re: Expanding list into string within a command |
Date: |
Sun, 6 Dec 2020 23:30:43 +0300 |
User-agent: |
Mutt/2.0 (3d08634) (2020-11-07) |
* arthur miller <arthur.miller@live.com> [2020-12-06 22:57]:
> "So I was thinking to use macro that will expand the list within a command."
>
> Try smth like this:
> (my-macro (command &rest list)
> (dolist (item `,@list)
> (dosnth with your list item here)))
>
> Kind of, if that is what yiu want, I am not sure really what you are after
> here, but I use that as an idiom quite a lot.
Thank you.
I had to use `apply' when passing `args' that I get from &rest
Now I have made the function better that takes input as string,
processes outside command and returns output as string:
(defun rcd-command-output-from-input (program input &rest args)
"Returns output from PROGRAM INPUT with optional ARGS"
(let* ((output (with-temp-buffer
(insert input)
(apply #'call-process-region nil nil program t t nil args)
(buffer-string))))
output))
Which is also handy for some text processing like:
(defun markdown (text)
(rcd-command-output-from-input "markdown" text))
(markdown "## Hello")
"<h2>Hello</h2>
"
Then I have improved the generic function to accept any `cs2cs'
format which is tool for conversion of geographic coordinates:
(defun syogm-cs2cs (coord-string &rest cs2cs-format)
(let* ((command "cs2cs")
(cs2cs (apply #'rcd-command-output-from-input command coord-string
cs2cs-format))
(output (string-trim cs2cs))
(output (split-string output "\t"))
(lat (pop output))
(output (split-string (car output) " "))
(lon (pop output)))
(format "%s %s" lat lon)))
And now this works:
(syogm-cs2cs "5d15'57.76\"S 35d8'22.65\"E" "-f" "%.6f" "+proj=latlong"
"+datum=WGS84" "+to" "+proj=latlong" "+datum=WGS84")
Then I can make new functions like:
(defun syogm-dms2dd (coord-string)
"Convert DMS degree, minutes and seconds notation to DD decimal notation"
(syogm-cs2cs coord-string "-f" "%.6f" "+proj=latlong" "+datum=WGS84" "+to"
"+proj=latlong" "+datum=WGS84"))
Then it converts to acceptable result from degree, minutes,
seconds to decimal notation:
(syogm-dms2dd "5d15'57.76\"S 35d8'22.65\"E")
"-5.266044 35.139625"
as then I can convert Ugandan UTM zone 36N with geodetic datum
ARC1960 easier to WGS84 system used on mobile devices and maps of
today:
(defun syogm-convert-arc-1964-utm-36N-to-wgs-84 (earthing-northing)
"Converts UTM Zone 36N Arc 1960 geodetic datum to WGS84"
(syogm-cs2cs earthing-northing "-f" "%.5f" "EPSG:21096" "EPSG:4326"))
(syogm-convert-arc-1964-utm-36N-to-wgs-84 "137878 -125964")
"-1.14052 29.74755"
Which is final result I wanted to get, as only so I can request
download of maps from online providers.
Although I have been doing that conversion myself with Common Lisp already, but
now I just wish to use external tool.
(defun ll-number (d)
(let ((l (- (length d) 1)))
(if (integerp (read-from-string (first-char d)))
(substring d 0 l)
d)))
(defun ll-parts (coord)
(let ((ll-list (split-by-one-space coord)))
(delete-if #'string-emptyp ll-list)
(setf ll-list (map 'list #'(lambda (s) (string-trim '(#\Space) s)) ll-list))
(setf ll-list (map 'list #'(lambda (s) (ll-number s)) ll-list))
ll-list))
(defun dms2dd-degrees (d)
(truncate d))
(defun dms2dd-minutes (m)
(float (/ m 60)))
(defun dms2dd-seconds (s)
(float (/ s 3600)))
(defun dms2dd (coord)
(let* ((ll-list (ll-parts coord))
(degrees (car ll-list))
(minutes (cadr ll-list))
(seconds (caddr ll-list))
(cardinal (cadddr ll-list))
(dd (+ (dms2dd-degrees (read-from-string degrees))
(dms2dd-minutes (read-from-string minutes))
(dms2dd-seconds (read-from-string seconds)))))
(if (or (string= "S" cardinal) (string= "W" cardinal))
(- dd)
dd)))