emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] Re: [BABEL] "unset" :var definitions for subtree


From: Dan Davison
Subject: [Orgmode] Re: [BABEL] "unset" :var definitions for subtree
Date: Fri, 11 Feb 2011 12:19:22 +0000
User-agent: Gnus/5.110011 (No Gnus v0.11) Emacs/24.0.50 (darwin)

"Eric Schulte" <address@hidden> writes:

> Rainer M Krug <address@hidden> writes:
>
>> On 02/10/2011 02:27 AM, Eric Schulte wrote:
>>> Rainer M Krug <address@hidden> writes:
>>>
>>>> Hi
>>>>
>>>> For one project, I am usinr org to write submit scripte to a cluster
>>>> runing torqu. The important bit in this is, that between the shebang and
>>>> the code, no other executable line must occur. As I am using variables
>>>> in org (:var) they will occur just after the shebang, which causes a
>>>> problem for torque. So, my question is, is there a way to "unset"
>>>> variables defined by using :var for a subtree?
>>>>
>>>
>>> Hi Rainer,
>>>
>>> Interesting question... unfortunately I don't think that removing
>>> variables from header arguments is possible under the current setup.
>>>
>>> Perhaps in your case you could add a function to the post-tangle hook,
>>> which recognizes when it is being called in a just-tangled torqu script
>>> (maybe by searching for a series of #PBS lines), and then removes any
>>> lines between the shebang and the first #PBS line?
>>
>> That is also an option - what I am using at the moment is to use
>> :no-expand as a code block specific header argument. But this raises the
>> other question:
>>
>> Can I set the :no-expand in a properties block? As far as I understand,
>> in the properties block I have the argument and the value - but what do
>> I do with :noexpand?
>>
>> :PROPERTIES:
>> :var: A=13
>> :no-expand
>> :END:
>>
>
> You can just set it to "yes" or really any value you like (the value
> will be ignored).  I did however have to add "no-expand" to the list of
> header argument names searched for in property blocks -- I just pushed
> up a patch to this effect.
>
>>
>>>
>>> More generally, I wonder what a natural method would be to allow
>>> unsetting of pre-set header arguments for local blocks or subtrees?
>>> This may only apply to the :var header argument, as most others have a
>>> default setting which can be actively set.  If you have any ideas for a
>>> natural syntax for such an operation I'd be happy to hear it.
>>
>> First solution (probably the easiest to implement) would be along the
>> lines of the :no-expand header argument -
>>
>> :expand-var yes
>> and
>> :expand-var no
>>
>> This could possibly be expanded to
>> :expand-var A B C
>>
>> which would expand only the variables A B and C
>>
>> One step further: one could define groups of variables, like
>> :var-group X=A,B,C
>> or a similar syntax
>>
>> and then
>> :expand-var X
>> would expand A B and C
>>
>> This all would not be real unset - but a possibility for unsetting would be
>>
>> :var B=
>>
>> or
>>
>> :var-unset B
>>
>> i.e. if no value is specified in :var, the variable will be removed
>> (i.e. unset) - one could also use a null value (if it exists in elisp):
>>
>> :var B=(null)
>>
>
> Thanks for the ideas,
>
> I think you're right that something along the lines of the above should
> be the easiest to implement, however after reading these suggestions,
> I'm thinking that more generally there are a couple of other header
> arguments which could need to be unset, namely
> - file
> - dir
> - session
> - shebang
> some of these (like session) accept a "none" value which has the effect
> of un-setting the header argument.
>
> It would be nice to generalize whatever solution we apply across all
> types of header argument (both for implementation and for user
> simplicity).

Some half thought-through suggestions. Sorry if this is a bit
disorganized.

I wonder whether we should be using Org property inheritance here. If it
were possible to turn off property inheritance temporarily for the
execution of the block, then it could be prevented from inheriting the
header args that you don't want it to inherit. Perhaps babel could offer
a :bind header argument, which specifies the values of lisp variables in
a let-binding which encloses the src block execution?

#+header: :bind org-babel-use-property-inheritance nil
#+begin_src sh :tangle script.sh :shebang #!/bin/bash
#$ -cwd
#+end_src

with a patch along these lines

+(defvar org-babel-use-property-inheritance t
+  "When looking for org-babel header arguments in in-buffer
+  properties, this variable is passed as the INHERIT argument to
+  the function `org-enrty-get'")
+
 (defvar org-file-properties)
 (defun org-babel-params-from-properties (&optional lang)
   "Retrieve parameters specified as properties.
@@ -864,7 +870,7 @@ may be specified in the properties of the current outline 
entry."
             (lambda (header-arg)
               (and (setq val
                          (or (condition-case nil
-                                 (org-entry-get (point) header-arg t)
+                                 (org-entry-get (point) header-arg 
org-babel-use-property-inheritance)
                                (error nil))
                              (cdr (assoc header-arg org-file-properties))))
                    (cons (intern (concat ":" header-arg))


In fact, that might be more widely useful in Org -- it would offer a
sort of 'subtree local variables', as an analog of buffer local
variables. Like any other babel variable, BIND could be set in a
property drawer, but perhaps other subtree-specific Org operations such
as export and tangling could honour BIND by enclosing their execution in
the appropriate let binding?  Variables bound by BIND in enclosing
subtrees should be shadowed by those bound in more local subtrees, of
course.

On a related note, I wonder whether the #+BABEL line should be
re-implemented so that it works via setting org-file-properties?
I.e. made equivalent to a #+PROPERTIES line?

Finally, a feature for babel power users could be to offer a hook
function which allows modification of the source block data structure
immediately prior to execution. In the babel code, source blocks are
basically converted into an elisp data structure that tends to be called
`info'. We could have org-babel-src-block-modification-hook each
function of which would be passed the value of info and given the
opportunity to change it just before execution. For anyone who's
prepared to write elisp, that would permit a wide class of
modifications, such as knocking out the :var variables.

And this hook could be set at a subtree level by a BIND property...

Dan




>  The simplest option would probably be to ensure that
> setting any header argument to :none would remove all instances of that
> header argument.  The only problem there is cases like var, where you
> might not want to remove all :var's.  Maybe this could be expanded
> s.t. :none could take arguments, e.g.
>
> :header :none(A, B)
>
> which would remove all instances of the "header" header argument whose
> value is or is named "A" or "B"?  Or does that look too funky?
>
>>
>> But this raises another question of mine:
>>
>> I tried to use two :var headers in a properties block, but it only used
>> the first - did I miss something here?
>>
>
> Nope, it appears that property blocks (like a hash) assume that there is
> only one instance of each key->value pair, so once it is satisfied it
> will quit looking for more instances.  Maybe the following alternative
> will suffice
>
> Best -- Eric
>
> ** two vars in a properties block -- not possible
>    :PROPERTIES:
>    :var:      test1=7
>    :var:      test2=8
>    :END:
>
> #+begin_src emacs-lisp
>   (message "test1=%S test2=%S" test1 test2)
> #+end_src
>
> results in Error
> : let: Symbol's value as variable is void: test2
>
> *** an alternative
>     :PROPERTIES:
>     :var:      tests=all-tests
>     :END:
>
> #+tblname: all-tests
> - 7
> - 8
>
> #+begin_src emacs-lisp :var eric=89
>   (message "test1=%S test2=%S" (first tests) (second tests))
> #+end_src
>
> #+results:
> : test1=7 test2=8
>
> _______________________________________________
> Emacs-orgmode mailing list
> Please use `Reply All' to send replies to the list.
> address@hidden
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode



reply via email to

[Prev in Thread] Current Thread [Next in Thread]