From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Jean Louis Newsgroups: gmane.emacs.help Subject: Re: How to run shell command with stream input, to get string output Date: Thu, 4 Jul 2019 22:33:25 +0200 Organization: START YOUR OWN GOLD MINE Message-ID: <20190704203325.GK8543@protected.rcdrun.com> References: <20190630223205.GA19895@protected.rcdrun.com> <875zomw7cf.fsf@mbork.pl> <20190701081716.GA11749@protected.rcdrun.com> <874l46w26t.fsf@mbork.pl> <20190701092400.GF11749@protected.rcdrun.com> <87v9wha9vk.fsf@mbork.pl> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="10788"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Mutt/1.10.1 (2018-07-13) Cc: GNU Emacs Help To: Marcin Borkowski Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Thu Jul 04 22:33:41 2019 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1hj8QG-0002fm-Jm for geh-help-gnu-emacs@m.gmane.org; Thu, 04 Jul 2019 22:33:40 +0200 Original-Received: from localhost ([::1]:48660 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hj8QF-0002uz-9z for geh-help-gnu-emacs@m.gmane.org; Thu, 04 Jul 2019 16:33:39 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:45650) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hj8Q6-0002uh-Ij for help-gnu-emacs@gnu.org; Thu, 04 Jul 2019 16:33:31 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hj8Q5-0005b6-8H for help-gnu-emacs@gnu.org; Thu, 04 Jul 2019 16:33:30 -0400 Original-Received: from stw1.rcdrun.com ([217.170.207.13]:47859) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hj8Q5-0005aL-0V for help-gnu-emacs@gnu.org; Thu, 04 Jul 2019 16:33:29 -0400 Original-Received: from protected.rcdrun.com (localhost [::1]) (AUTH: PLAIN admin, TLS: TLS1.2,256bits,ECDHE_RSA_AES_256_GCM_SHA384) by stw1.rcdrun.com with ESMTPSA; Thu, 04 Jul 2019 13:33:26 -0700 id 0000000000020360.000000005D1E6296.00007AC1 Original-Received: from localhost (protected.rcdrun.com [local]) by protected.rcdrun.com (OpenSMTPD) with ESMTPA id e6c13257; Thu, 4 Jul 2019 20:33:25 +0000 (UTC) Content-Disposition: inline In-Reply-To: <87v9wha9vk.fsf@mbork.pl> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 217.170.207.13 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.org gmane.emacs.help:121100 Archived-At: * Marcin Borkowski [2019-07-04 21:19]: > > The data is not in files, it is in the database. > > Ah, now that finally makes sense to me. > > Unfortunately, I can't help with this - but thanks for your patience, > I didn't get the problem earlier. Majority of Website Revision Systems require some templating mechanism, so I am just moving from Common Lisp CL-EMB to doing the same in emacs. Reference to Website Revision System: https://www.gnu.org/philosophy/words-to-avoid.html#Content I started with this one, it works reasonably well for faxing from Emacs. Imagine multiple templates, multiple faxes, variables like first name, last name, fax numbers, need to be replaced in the templates. (defun rcd/expand-@template@ (template plist) "Expands the template that contains @vars@ with plist member values from plist" (let ((rx (rx "@" (group (one-or-more (or (any alpha) "_"))) "@"))) (with-temp-buffer (insert template) (goto-char 0) (while (re-search-forward rx nil t) (let* ((var-found (match-string 1)) (var-plist (or (plist-get plist (intern var-found)) "")) (var-plist (if (numberp var-plist) (number-to-string var-plist) var-plist))) (replace-match var-plist nil nil))) (buffer-string)))) (defun rcd/xml-escape (any) (let ((type (type-of any))) (cond ((eq 'string type) (xml-escape-string any)) ((eq 'integer type) (number-to-string any))))) This one works better than xml-escape-string for my purposes, maybe it is not efficient, but the other one is not working in my templates. (defun xml-escape (string) "Escape XML without matching problems" (let ((chars (string-to-list string)) (nlist '())) (dolist (c chars (list-of-strings-to-string (reverse nlist))) (let ((char (char-to-string c))) (push (cond ((string= ">" char) ">") ((string= "<" char) "<") ((string= "\"" char) """) ((string= "'" char) "'") ((string= "&" char) "&") (t char)) nlist))))) (defun rcd/expand-<%template%>-plist (template plist) "Expands the template that contains <% var %> with plist member values from plist" (let ((rx (rx "<%" (one-or-more (or blank "\n")) (group (minimal-match (one-or-more (or (any alpha) "-" "_")))) (one-or-more (or blank "\n")) "-escape" (one-or-more (or blank "\n")) "%>"))) (with-temp-buffer (insert template) (goto-char (point-min)) (while (re-search-forward rx nil t) (let* ((var-found (match-string 1)) (value-found (or (plist-get plist (intern var-found)) nil)) (var-plist (if value-found (plist-get plist (intern var-found)) nil))) (if (and var-found value-found var-plist) (replace-match (xml-escape var-plist) nil nil) (replace-match (concat "<% " var-found " %>") nil nil)))) (let ((rx2 (rx "<%" (one-or-more (or blank "\n")) (group (minimal-match (one-or-more (or (any alpha) "-" "_")))) (one-or-more (or blank "\n")) "%>"))) (goto-char (point-min)) (while (re-search-forward rx2 nil t) (let* ((var-found (match-string 1)) (value-found (or (plist-get plist (intern var-found)) nil)) (var-plist (if value-found (or (plist-get plist (intern var-found)) (concat "<% " var-found " %>"))))) (if (and var-found value-found) (replace-match var-plist nil nil) (replace-match (concat "<% " var-found " %>" nil nil))))) (buffer-string))))) (defun rcd/expand-<%template%>-eval (template) (let ((rx (rx "<%" (one-or-more (or blank "\n")) (group (minimal-match (one-or-more anything))) (one-or-more (or blank "\n")) "%>"))) (with-temp-buffer (insert template) (goto-char (point-min)) (while (re-search-forward rx nil t) (let* ((eval-found (match-string 1)) (eval-value (condition-case nil (eval (car (read-from-string eval-found))) (error ""))) (eval-value (if eval-value (format "%s" eval-value) ""))) (if eval-found (replace-match eval-value nil nil) (replace-match "" nil nil)))) (buffer-string)))) (defun rcd/expand-<%template%> (template plist) "Expands <% templates %> with plist, global variables and any functions" (let* ((plist (rcd/expand-<%template%>-plist template plist)) (eval (rcd/expand-<%template%>-eval plist))) eval)) (defun gold-price-kg () 45553.12) And here is working example. ;; (rcd/expand-<%template%> "<% (gold-price-kg) %> {<% title-some -escape %>} {<% title-some %>}" '(title-some "<>")) If somebody wish to propose better regex let me know. Jean