emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Tangling flow control
@ 2016-11-08 21:21 Philip Hudson
  2016-11-09 17:54 ` Charles C. Berry
  0 siblings, 1 reply; 7+ messages in thread
From: Philip Hudson @ 2016-11-08 21:21 UTC (permalink / raw)
  To: emacs orgmode-mailinglist

Thanks to Charles Berry and the "scraps" site curated by Eric Schulte
(is he on the list?), I now know how to do "branching" flow control
when tangling, by using a form that evals to either "no" or a filename
as the argument to the =:tangle= header.

How do you do "looping" flow control?

For context, what I'm trying to write is a single Org file from which
I can tangle out a number of =~/.ssh/config= files, one for each of
several hosts on a LAN. Within this file I need to repeatedly place a
template =BEGIN_SRC ssh-config= block, each time with a few words and
numbers changed. Do you do this anywhere? If so, how have you
implemented it?

I'm already at the point where I can do a dumb, brute-force version
with lots of near-identical blocks that I know will give me what I
need, so that's fine, but I like to keep things DRY.

It occurs to me that looping may simply not be what tangling is for,
and I need to look at levels of indirection. That is, tangle to a
bunch of intermediate Org files each of which tangles to a config
file: is that what you would recommend? Or transclude an Org file
containing my block template and perhaps somehow use tags and
=org-get-tags-at= to parameterize each inclusion? Anyone already doing
something like that?

-- 
Phil Hudson                  http://hudson-it.ddns.net
Pretty Good Privacy (PGP) ID: 0x887DCA63

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

* Re: Tangling flow control
  2016-11-08 21:21 Tangling flow control Philip Hudson
@ 2016-11-09 17:54 ` Charles C. Berry
  2016-11-09 20:32   ` Philip Hudson
  0 siblings, 1 reply; 7+ messages in thread
From: Charles C. Berry @ 2016-11-09 17:54 UTC (permalink / raw)
  To: Philip Hudson; +Cc: emacs orgmode-mailinglist

On Tue, 8 Nov 2016, Philip Hudson wrote:

[snip]
>
> How do you do "looping" flow control?
>
> For context, what I'm trying to write is a single Org file from which
> I can tangle out a number of =~/.ssh/config= files, one for each of
> several hosts on a LAN. Within this file I need to repeatedly place a
> template =BEGIN_SRC ssh-config= block, each time with a few words and
> numbers changed. Do you do this anywhere? If so, how have you
> implemented it?
>


It sounds like what you want is a template for the src block and another 
src block that does substitutions in that template using a table of 
values inside a loop.

Just to get you started, with this template:

#+NAME: template
#+BEGIN_SRC org
   ,#+BEGIN_SRC shell :tangle %to-file
   ls -lt %filename
   ,#+END_SRC
#+END_SRC

and this helper src-block

#+NAME: get-body
#+BEGIN_SRC emacs-lisp :var src-block-name="c-code"
   (save-excursion
     (org-babel-goto-named-src-block
      src-block-name)
     (cadr (org-babel-get-src-block-info)))

#+END_SRC


running

#+header: :wrap src org :var tmpl=get-body("template")
#+BEGIN_SRC emacs-lisp
   (org-fill-template tmpl
     '(("to-file" . "abc.sh")("filename" . "my-dir")))
#+END_SRC

yields

#+RESULTS:
#+BEGIN_src org
,#+BEGIN_SRC shell :tangle abc.sh
ls -lt my-dir
,#+END_SRC
#+END_src


To revise this for your application, you need to provide a table of the 
associated values for the "to-file" and "filename" keys in the alist, read 
that table using a :var header, loop thru the table reconstructing the 
alist each time creating src blocks, and send the output to an org 
tempfile.  Then you tangle the tempfile.

Alternatively, you simply write the script files directly without 
bothering to write to an org tempfile.

HTH,

Chuck

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

* Re: Tangling flow control
  2016-11-09 17:54 ` Charles C. Berry
@ 2016-11-09 20:32   ` Philip Hudson
  2016-11-09 21:41     ` Charles C. Berry
  0 siblings, 1 reply; 7+ messages in thread
From: Philip Hudson @ 2016-11-09 20:32 UTC (permalink / raw)
  To: Charles C. Berry; +Cc: emacs orgmode-mailinglist

On 9 November 2016 at 17:54, Charles C. Berry <ccberry@ucsd.edu> wrote:
> On Tue, 8 Nov 2016, Philip Hudson wrote:
>
> [snip]
>>
>> How do you do "looping" flow control?
>>
>> For context, what I'm trying to write is a single Org file from which
>> I can tangle out a number of =~/.ssh/config= files, one for each of
>> several hosts on a LAN. Within this file I need to repeatedly place a
>> template =BEGIN_SRC ssh-config= block, each time with a few words and
>> numbers changed. Do you do this anywhere? If so, how have you
>> implemented it?
>
> It sounds like what you want is a template for the src block and another src
> block that does substitutions in that template using a table of values
> inside a loop.
>
> Just to get you started, with this template:
>
> #+NAME: template
> #+BEGIN_SRC org
>   ,#+BEGIN_SRC shell :tangle %to-file
>   ls -lt %filename
>   ,#+END_SRC
> #+END_SRC
>
> and this helper src-block
>
> #+NAME: get-body
> #+BEGIN_SRC emacs-lisp :var src-block-name="c-code"
>   (save-excursion
>     (org-babel-goto-named-src-block
>      src-block-name)
>     (cadr (org-babel-get-src-block-info)))
>
> #+END_SRC
>
>
> running
>
> #+header: :wrap src org :var tmpl=get-body("template")
> #+BEGIN_SRC emacs-lisp
>   (org-fill-template tmpl
>     '(("to-file" . "abc.sh")("filename" . "my-dir")))
> #+END_SRC
>
> yields
>
> #+RESULTS:
> #+BEGIN_src org
> ,#+BEGIN_SRC shell :tangle abc.sh
> ls -lt my-dir
> ,#+END_SRC
> #+END_src
>
>
> To revise this for your application, you need to provide a table of the
> associated values for the "to-file" and "filename" keys in the alist, read
> that table using a :var header, loop thru the table reconstructing the alist
> each time creating src blocks, and send the output to an org tempfile.  Then
> you tangle the tempfile.
>
> Alternatively, you simply write the script files directly without bothering
> to write to an org tempfile.

Thanks Chuck. I think I've got that straight. I hadn't come across
`org-fill-template' before. I think I know how to loop thru a table,
though I haven't done it myself before; I've seen how to "get" a table
as a list.

What I'm not clear about is why the template nests a shell-script
block inside an Org block. Should the outer Org block not have a
%-escaped placeholder for a :tangle target, an intermediate Org file?

-- 
Phil Hudson                  http://hudson-it.ddns.net
Pretty Good Privacy (PGP) ID: 0x887DCA63

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

* Re: Tangling flow control
  2016-11-09 20:32   ` Philip Hudson
@ 2016-11-09 21:41     ` Charles C. Berry
  2016-11-09 22:59       ` Philip Hudson
  0 siblings, 1 reply; 7+ messages in thread
From: Charles C. Berry @ 2016-11-09 21:41 UTC (permalink / raw)
  To: Philip Hudson; +Cc: emacs orgmode-mailinglist

On Wed, 9 Nov 2016, Philip Hudson wrote:

> On 9 November 2016 at 17:54, Charles C. Berry <ccberry@ucsd.edu> wrote:
>> On Tue, 8 Nov 2016, Philip Hudson wrote:
>>
>> [snip]
>>>
>>> How do you do "looping" flow control?
>>>
>>> For context, what I'm trying to write is a single Org file from which
>>> I can tangle out a number of =~/.ssh/config= files, one for each of
>>> several hosts on a LAN. Within this file I need to repeatedly place a
>>> template =BEGIN_SRC ssh-config= block, each time with a few words and
>>> numbers changed. Do you do this anywhere? If so, how have you
>>> implemented it?
>>
>> It sounds like what you want is a template for the src block and another src
>> block that does substitutions in that template using a table of values
>> inside a loop.
>>
>> Just to get you started, with this template:
>>
>> #+NAME: template
>> #+BEGIN_SRC org
>>   ,#+BEGIN_SRC shell :tangle %to-file
>>   ls -lt %filename
>>   ,#+END_SRC
>> #+END_SRC
>>
>> and this helper src-block
>>
>> #+NAME: get-body
>> #+BEGIN_SRC emacs-lisp :var src-block-name="c-code"
>>   (save-excursion
>>     (org-babel-goto-named-src-block
>>      src-block-name)
>>     (cadr (org-babel-get-src-block-info)))
>>
>> #+END_SRC
>>
>>
>> running
>>
>> #+header: :wrap src org :var tmpl=get-body("template")
>> #+BEGIN_SRC emacs-lisp
>>   (org-fill-template tmpl
>>     '(("to-file" . "abc.sh")("filename" . "my-dir")))
>> #+END_SRC
>>
>> yields
>>
>> #+RESULTS:
>> #+BEGIN_src org
>> ,#+BEGIN_SRC shell :tangle abc.sh
>> ls -lt my-dir
>> ,#+END_SRC
>> #+END_src
>>
>>
>> To revise this for your application, you need to provide a table of the
>> associated values for the "to-file" and "filename" keys in the alist, read
>> that table using a :var header, loop thru the table reconstructing the alist
>> each time creating src blocks, and send the output to an org tempfile.  Then
>> you tangle the tempfile.
>>
>> Alternatively, you simply write the script files directly without bothering
>> to write to an org tempfile.
>
> Thanks Chuck. I think I've got that straight. I hadn't come across
> `org-fill-template' before. I think I know how to loop thru a table,
> though I haven't done it myself before; I've seen how to "get" a table
> as a list.
>
> What I'm not clear about is why the template nests a shell-script
> block inside an Org block. Should the outer Org block not have a
> %-escaped placeholder for a :tangle target, an intermediate Org file?

No.

The org src block is just a container. Its body is a src block template 
that gets copied into the variable `tmpl', which if filled and placed in 
file can be tangled.

Alternatively, you can eval (setq tmpl "<template string>") somewhere 
(maybe in a local variables block), where the <template string> part is 
the template.

But it seems easier to edit the template as an org src block - C-c ' puts 
your template in an OrgSrc buffer, then moving point to a src block and 
typing M-x org-edit-src-code puts its body in another OrgSrc buffer where 
you can edit it in the shell-mode or whatever mode.

Also, I suppose that template should have been an ssh-config src block to 
conform with your earlier posting. But I think you get the idea.

Chuck

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

* Re: Tangling flow control
  2016-11-09 21:41     ` Charles C. Berry
@ 2016-11-09 22:59       ` Philip Hudson
  2016-11-10  1:19         ` Charles C. Berry
  0 siblings, 1 reply; 7+ messages in thread
From: Philip Hudson @ 2016-11-09 22:59 UTC (permalink / raw)
  To: Charles C. Berry; +Cc: emacs orgmode-mailinglist

On 9 November 2016 at 21:41, Charles C. Berry <ccberry@ucsd.edu> wrote:
> The org src block is just a container. Its body is a src block template that
> gets copied into the variable `tmpl', which if filled and placed in file can
> be tangled.

That makes sense, but it seems to conflict with what you illustrate:

#+RESULTS:
#+BEGIN_src org
,#+BEGIN_SRC shell :tangle abc.sh
ls -lt my-dir
,#+END_SRC
#+END_src

I'd expect/want:

#+RESULTS:
#+BEGIN_SRC shell :tangle abc.sh
ls -lt my-dir
#+END_SRC

Wouldn't I?


> Alternatively, you can eval (setq tmpl "<template string>") somewhere (maybe
> in a local variables block), where the <template string> part is the
> template.
>
> But it seems easier to edit the template as an org src block - C-c ' puts
> your template in an OrgSrc buffer, then moving point to a src block and
> typing M-x org-edit-src-code puts its body in another OrgSrc buffer where
> you can edit it in the shell-mode or whatever mode.
>
> Also, I suppose that template should have been an ssh-config src block to
> conform with your earlier posting. But I think you get the idea.

Yes, that's no problem, I adapt it mutatis mutandum.

-- 
Phil Hudson                  http://hudson-it.ddns.net
Pretty Good Privacy (PGP) ID: 0x887DCA63

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

* Re: Tangling flow control
  2016-11-09 22:59       ` Philip Hudson
@ 2016-11-10  1:19         ` Charles C. Berry
  2016-11-10 10:36           ` Philip Hudson
  0 siblings, 1 reply; 7+ messages in thread
From: Charles C. Berry @ 2016-11-10  1:19 UTC (permalink / raw)
  To: Philip Hudson; +Cc: emacs orgmode-mailinglist

On Wed, 9 Nov 2016, Philip Hudson wrote:

> On 9 November 2016 at 21:41, Charles C. Berry <ccberry@ucsd.edu> wrote:
>> The org src block is just a container. Its body is a src block template that
>> gets copied into the variable `tmpl', which if filled and placed in file can
>> be tangled.
>
> That makes sense, but it seems to conflict with what you illustrate:
>
> #+RESULTS:
> #+BEGIN_src org
> ,#+BEGIN_SRC shell :tangle abc.sh
> ls -lt my-dir
> ,#+END_SRC
> #+END_src
>
> I'd expect/want:
>
> #+RESULTS:
> #+BEGIN_SRC shell :tangle abc.sh
> ls -lt my-dir
> #+END_SRC
>
> Wouldn't I?


For sure. But when developing stuff like this `:wrap src org' will capture 
it and protect against messing up the rest of your *.org file.

Once you get it filling the template as you want it, remove the :wrap 
header and add a `:file script.org' header

But it is indeed optional.

Chuck

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

* Re: Tangling flow control
  2016-11-10  1:19         ` Charles C. Berry
@ 2016-11-10 10:36           ` Philip Hudson
  0 siblings, 0 replies; 7+ messages in thread
From: Philip Hudson @ 2016-11-10 10:36 UTC (permalink / raw)
  To: Charles C. Berry; +Cc: emacs orgmode-mailinglist

On 10 November 2016 at 01:19, Charles C. Berry <ccberry@ucsd.edu> wrote:
> when developing stuff like this `:wrap src org' will capture it and protect
> against messing up the rest of your *.org file.


My goodness, you think of everything! Thanks very much Charles.

-- 
Phil Hudson                  http://hudson-it.ddns.net
Pretty Good Privacy (PGP) ID: 0x887DCA63

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

end of thread, other threads:[~2016-11-10 10:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-08 21:21 Tangling flow control Philip Hudson
2016-11-09 17:54 ` Charles C. Berry
2016-11-09 20:32   ` Philip Hudson
2016-11-09 21:41     ` Charles C. Berry
2016-11-09 22:59       ` Philip Hudson
2016-11-10  1:19         ` Charles C. Berry
2016-11-10 10:36           ` Philip Hudson

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).