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 13:41:08 +0000
User-agent: Gnus/5.110011 (No Gnus v0.11) Emacs/24.0.50 (darwin)

Rainer M Krug <address@hidden> writes:

> On 02/11/2011 01:19 PM, Dan Davison wrote:
>> "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?

>
> The whole logic in org is that, if I understand correctly, of the
> smaller unit (e.g. file -> subtree -> ... -> code block) inheriting
> properties, variables, ... from the next larger unit - introducing a
> possibility to disable inheritance, would introduce a completely new
> level of complexity.
> I think that one should rather introduce a way of
> unsetting e.g. variable values to have the same effect, but still
> sticking with the whole inheritance logic.
> I reslly think that it might be dangerous to open the possibility to
> break this inheritance principle.

Hi Rainer,

Org already has a way to disable inheritance in general, and on a
property-by-property basis. See

http://orgmode.org/manual/Property-inheritance.html#Property-inheritance

and the docstrings for the variable org-use-property-inheritance and the
function org-entry-get.

It seems that what you want to do can be described as disabling
inheritance of the :var properties for a specific block. So I'm
suggesting that it may be more parsimonious to do this with the existing
Org inheritance mechanisms than to introduce new babel header arguments
specifically for this purpose.

>
>>
>> #+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.
>
> If I define a variable in a PROPERTIES block, it is only valid in the
> subtree - so don't we have that already?

Here I was talking about emacs-lisp variables being "local to a
particular subtree"; as opposed to Org properties.

>> 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?
>
> Yes please - I was not even aware that they were gone

They are not gone. By "re-implemented" I mean implemented in a different
way from how they are currently implemented.

> - only surprised
> that some things did not work any more as expected.
>
> So how can I now define multiple variables?

I don't know :)

> in a properties drawer multiple :var does not work? Could you give a
> simple example how to define variables A and B?

Yes, I've always been a bit uncomfortable with this. As Eric says, Org
properties are supposed to be a bit like a hash, with unique keys.

>
> I think I am now completely confused.
>
>>
>> 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...
>
> Sorry - now you have lost me.

> All I suggested was a way to unset a variable ...

I am also suggesting some possible ways to do that, while trying to
avoid special-case solutions. The issue you raised initially was not how
to unset variables, but rather how to prevent stuff getting inbetween
the shebang and the torque options, but it has led to some interesting
ideas. We should probably bear in mind that unsetting variables is
really a hack in the context of your original problem. Even if we make
it possible, what is the solution when we want the variables?

Dan


>
>
>>
>> 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]