Re: [O] question on org-element-interpret-data and when it works

2018-03-03 Thread Thorsten Jolitz
Nicolas Goaziou  writes:

> Thorsten Jolitz  writes:
>
>> You used the word 'discrepancy',
>
> True. I inferred it from
>
>   (funny enough, some org elements have 'value' as their content, others
>   'content').
>
> which, IMO, sounds like it is a surprising fact.
>
>> I simply needed to know for each org
>> element what is interpreted and what not. And some have a content,
>> others a :value.
>
> As in every AST, some nodes are terminal (no contents), and some are not
> (contents).
>
> This distinction is made in `org-element-greater-elements', i.e.,
> non-terminal elements. See also `org-element-recursive-objects' for
> non-terminal objects.
>
>> So if I pass 'Hello World' as content to an example
>> block, nothing happens, if I pass it via :value, it appears as the
>> blocks ... well, content.
>
> Contents imply Org syntax. This would defeat the purpose of an example
> block.

Ok, so its just a matter of wording.  

On the computer science side of things, content seems to be org elements
or objects contained in other org elements (like table rows in a table),
and on the laymans side of things the text inside of an example block
looks very much like the blocks content too (while its technically named
'value' in this case).

-- 
cheers,
Thorsten




Re: [O] question on org-element-interpret-data and when it works

2018-03-03 Thread Nicolas Goaziou
Thorsten Jolitz  writes:

> You used the word 'discrepancy',

True. I inferred it from

  (funny enough, some org elements have 'value' as their content, others
  'content').

which, IMO, sounds like it is a surprising fact.

> I simply needed to know for each org
> element what is interpreted and what not. And some have a content,
> others a :value.

As in every AST, some nodes are terminal (no contents), and some are not
(contents).

This distinction is made in `org-element-greater-elements', i.e.,
non-terminal elements. See also `org-element-recursive-objects' for
non-terminal objects.

> So if I pass 'Hello World' as content to an example
> block, nothing happens, if I pass it via :value, it appears as the
> blocks ... well, content.

Contents imply Org syntax. This would defeat the purpose of an example
block.




Re: [O] question on org-element-interpret-data and when it works

2018-03-03 Thread Thorsten Jolitz
Nicolas Goaziou  writes:

> Thorsten Jolitz  writes:
>
>> I have defined these two constants in org-dp.el to work around this
>> discrepancy (and to know which elements do not have interpreted content
>> at all):
>>
>> ,
>> | (defconst org-dp-no-content-elems
>> |   (list 'babel-call 'clock 'comment 'comment-block 'diary-sexp
>> |'example-block 'fixed-width 'horizontal-rule 'keyword
>> |'latex-environment 'node-property 'planning 'src-block)
>> |   "List of Org elements without interpreted .")
>> | 
>> | (defconst org-dp-value-blocks
>> |   (list 'comment-block 'example-block 'src-block)
>> |   "List of Org block that have a :value instead of contents.")
>> `
>
> I don't understand where you think there is a discrepancy here.

You used the word 'discrepancy', I simply needed to know for each org
element what is interpreted and what not. And some have a content,
others a :value. So if I pass 'Hello World' as content to an example
block, nothing happens, if I pass it via :value, it appears as the
blocks ... well, content.

This is no critique, and no problem, and please don't change it (since
it would be a breaking change in this context). 

With the org-dp tempo-templates, its no problem for org-dp users either,
since these are smart: they offer you a content arg (cont) to fill, if
it makes sense, they hide it, if not. And for some block types they
offer the :value parameter, since it is interpreted.

So I don't see any problem, just something an org-dp user probably
should be aware of.

-- 
cheers,
Thorsten




Re: [O] question on org-element-interpret-data and when it works

2018-03-03 Thread Nicolas Goaziou
Thorsten Jolitz  writes:

> I have defined these two constants in org-dp.el to work around this
> discrepancy (and to know which elements do not have interpreted content
> at all):
>
> ,
> | (defconst org-dp-no-content-elems
> |   (list 'babel-call 'clock 'comment 'comment-block 'diary-sexp
> | 'example-block 'fixed-width 'horizontal-rule 'keyword
> | 'latex-environment 'node-property 'planning 'src-block)
> |   "List of Org elements without interpreted .")
> | 
> | (defconst org-dp-value-blocks
> |   (list 'comment-block 'example-block 'src-block)
> |   "List of Org block that have a :value instead of contents.")
> `

I don't understand where you think there is a discrepancy here.



Re: [O] question on org-element-interpret-data and when it works

2018-03-03 Thread Thorsten Jolitz
Nicolas Goaziou  writes:

Hello,

> Thorsten Jolitz  writes:
>
>> (funny enough, some org elements have 'value' as their content, others
>> 'content').
>
> Could you point out where there is such discrepancy in "org-element.el"?

I have defined these two constants in org-dp.el to work around this
discrepancy (and to know which elements do not have interpreted content
at all):

,
| (defconst org-dp-no-content-elems
|   (list 'babel-call 'clock 'comment 'comment-block 'diary-sexp
|   'example-block 'fixed-width 'horizontal-rule 'keyword
|   'latex-environment 'node-property 'planning 'src-block)
|   "List of Org elements without interpreted .")
| 
| (defconst org-dp-value-blocks
|   (list 'comment-block 'example-block 'src-block)
|   "List of Org block that have a :value instead of contents.")
`

PS 
should probably read "... without interpreted content" in the first
defconst

-- 
cheers,
Thorsten




Re: [O] question on org-element-interpret-data and when it works

2018-03-03 Thread Nicolas Goaziou
Hello,

Thorsten Jolitz  writes:

> (funny enough, some org elements have 'value' as their content, others
> 'content').

Could you point out where there is such discrepancy in "org-element.el"?

Thank you.

Regards,

-- 
Nicolas Goaziou



Re: [O] question on org-element-interpret-data and when it works

2018-03-03 Thread Thorsten Jolitz
John Kitchin  writes:

Hello John,

> I am trying to find some ways to programatically modify org-elements
> that use fewer regexps and motion commands. It seems like org-dp
> (https://github.com/tj64/org-dp) was intended to do that

thats right, that's it's exact use case

> but it is not clear enough how you might use it, and it also doesn't
> seem to support plain-lists yet.

it's actually split into core and lib functionality, org-dp.el being the
core and org-dp-lib.el being the lib.

AFAIK it org-dp does work, and in its core it's based on just two
commands, one for CREATE and one for REWIRE (=modify) org elements
(locally, not replacing Nicolas org element framework, but rather making
it easy to use locally without the need for a whole parse tree).

The basic idea:
 - internally, all org elements look alike (plists)
 - org elements have many properties, but we are interested only in
   those used by the org element interpreter (that creates org syntax
   out of Emacs Lisp plists). These are surprisingly few.
 - luckily, plists ignore all elements that are not accessed, making
   transformation between different plists for different org elements
   much easier

You should be able to do anything you want with org elements with just
these two functions, org-dp-create and org-dp-rewire.

There is a generic prompt function two. Never write interactive specs
again, just use this one prompt functions for all org element related
prompts (or utility commands based on the prompt workhorse).

And then there is this fast and simple mapping function for org-dp:

,[ C-h f org-dp-map RET ]
| org-dp-map is a Lisp function in ‘org-dp.el’.
| 
| (org-dp-map FUN-WITH-ARGS RGXP  MATCH-POS BACKWARD-SEARCH-P
| BEG END SILENT-P)
| 
| Apply quoted FUN-WITH-ARGS at every RGXP match.
| 
| [...] 
| In contrast to other mapping functions in Org-mode, this mapping
| function does not collect any information about mapped elements,
| it simply moves point quickly to all positions in a buffer(range)
| that are matched by a (forward) regexp-search and applies one of
| ‘org-dp’’s or ‘org-dp-lib’’s functions locally at that
| point (i.e. without any context information other than that about
| the parsed element-at-point).
| 
| When calling FUN ‘org-dp-create’, or ‘org-dp-rewire’ with
| argument ELEMENT given, no parsing at all takes places, but newly
| created of modified elements can be inserted at point.
| 
| This mapping function wraps its body in ‘save-excursion’ and
| ‘save-match-data’ calls, so point position and global match-data
| are preserved. It does not widen the buffer before executing its
| body, so buffer restrictions are respected. 
`

> What I imagined happening is that I would get the element to modify as a
> data structure, modify the data structure, and replace the old element
> with an interpreted version of the modified data structure.

Thats exactly what this central org-dp workhorse function does:

,[ C-h f org-dp-rewire RET ]
| org-dp-rewire is a Lisp function in ‘org-dp.el’.
| 
| (org-dp-rewire ELEM-TYPE  CONTENTS REPLACE AFFILIATED ELEMENT
|  ARGS)
| 
| Rewire element-at-point or ELEMENT (if given).
| 
| [...] 
| ELEM-TYPE is one of the types in ‘org-element-all-elements’. If
| it is nil, the element type of the original element is used. ARGS
| is a plist consisting of key-val pairs of all other keyword
| arguments given, defining the (rewired) element’s properties.
| 
| The former value of an element property can be reused in the
| creation of a new value by giving a ‘lambda’ expession or
| function taking two arguments (instead of just a value) to a
| key. The first argument will then be replaced by the property’s
| former value when applying the function. The second argument
| should be the parsed element itself, enabling access to its type
| and all its properties inside of the lambda expression.
`

But, as Nicolas said in his answer, plain lists, tables, properties
etc are nested org elements, what is most obvious with tables:
a table is just a container for table rows that hold the actual data
(with some meta data in the container).

Thats why org-dp-lib.el has several related functions:

,
| org-dp-lib.el
| 40:(defun org-dp-wrap-in-block ( lines user-info  prompt-spec)
| 204:(defun org-dp-toggle-headers ( action)
| 290:(defun org-dp-org-props ()
| 307:(defun org-dp-filter-node-props (filter  negate-p verbose-p)
| 366:(defun org-dp-create-table (row-lst  tblfm table-el-p insert-p)
| 416:(defun org-dp-create-plain-list (item-lst  insert-p)
| 452:(defun org-dp-create-property-drawer (node-prop-lst  insert-p)
`

They should hopefully be pretty well documented, since I use to do that.

To get started with org-dp, you really need these 3 (or 4)
functions. They spare you typing, and more important, they tell which
properties of an org element matter for its interpretation.

CREATE:

,[ C-h f tempo-template-org-dp-create RET ]
| tempo-template-org-dp-create 

Re: [O] question on org-element-interpret-data and when it works

2018-02-26 Thread Nicolas Goaziou
Hello,

John Kitchin  writes:

> I am trying to find some ways to programatically modify org-elements that
> use fewer regexps and motion commands. It seems like org-dp (
> https://github.com/tj64/org-dp) was intended to do that but it is not clear
> enough how you might use it, and it also doesn't seem to support
> plain-lists yet.

[...]

> It works on some things, e.g. headlines, src blocks. I put the point on one
> of those things, run this command, and then I can paste it somewhere to see
> that it did indeed work.
>
> But, it does not work on plain-lists, or paragraphs. I either get an empty
> string, or Wrong type argument: char-or-string-p, nil
>
> Is it possible to do what I am describing? Am I just missing how to get the
> element data in the right form?

You cannot change a non-terminal element without changing its contents.
In particular plain-lists, tables and paragraphs are fully defined by
their contents, i.e., they do not decorate contents like headlines. In
this case, data returned by `org-element-context' is incomplete in this
case. You probably need to parse the buffer between :begin and :end and
modify structure recursively.

Regards,

-- 
Nicolas Goaziou



[O] question on org-element-interpret-data and when it works

2018-02-25 Thread John Kitchin
I am trying to find some ways to programatically modify org-elements that
use fewer regexps and motion commands. It seems like org-dp (
https://github.com/tj64/org-dp) was intended to do that but it is not clear
enough how you might use it, and it also doesn't seem to support
plain-lists yet.

What I imagined happening is that I would get the element to modify as a
data structure, modify the data structure, and replace the old element with
an interpreted version of the modified data structure.

I want to do something like a radio list where only one box can be checked
at a time. Suppose I have this:

#+attr_org: :radio
- [ ] one
- [ ] two
- [ ] three

It gets represented from org-element-context as:

(plain-list
 (:type unordered :begin 579 :end 630 :contents-begin 598 :contents-end 630
:structure
((598 0 "- " nil "[ ]" nil 608)
(608 0 "- " nil "[ ]" nil 618)
(618 0 "- " nil "[ ]" nil 630))
:post-blank 0 :post-affiliated 598 :attr_org
(":radio")
:parent nil))

What I thought I could is something like (here I simulate having point in
the first item):

#+BEGIN_SRC emacs-lisp :results code
(let* ((p 600) ;where current point is
   n
   (data '(plain-list
   (:type unordered :begin 579 :end 630 :contents-begin 598
:contents-end 630 :structure
  ((598 0 "- " nil "[ ]" nil 608)
   (608 0 "- " nil "[ ]" nil 618)
   (618 0 "- " nil "[ ]" nil 630))
  :post-blank 0 :post-affiliated 598 :attr_org
  (":radio")
  :parent nil)))
   (structure (plist-get (cadr data) :structure)))
  (loop for i from 0 for item in structure
do
(if (and (>= p (first item))
(< p (seventh item)))
;; in the item, toggle it
(setf (fifth item) (if (string= "[X]" (fifth item))
   "[ ]"
"[X]"))
  ;; not on the item
  (setf (fifth item) "[ ]")))

  data)
#+END_SRC

Which outputs:

#+RESULTS:
#+BEGIN_SRC emacs-lisp
(plain-list
 (:type unordered :begin 579 :end 630 :contents-begin 598 :contents-end 630
:structure
((598 0 "- " nil "[X]" nil 608)
(608 0 "- " nil "[ ]" nil 618)
(618 0 "- " nil "[ ]" nil 630))
:post-blank 0 :post-affiliated 598 :attr_org
(":radio")
:parent nil))
#+END_SRC

As a step towards getting to a data structure I could programmatically
modify, and then reinterpret, I made this little function:

(defun ointerp ()
  (interactive)
  (let ((el (org-element-context)))
(kill-new (org-element-interpret-data el

It works on some things, e.g. headlines, src blocks. I put the point on one
of those things, run this command, and then I can paste it somewhere to see
that it did indeed work.

But, it does not work on plain-lists, or paragraphs. I either get an empty
string, or Wrong type argument: char-or-string-p, nil

Is it possible to do what I am describing? Am I just missing how to get the
element data in the right form?

Thanks,



John

---
Professor John Kitchin
Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon University
Pittsburgh, PA 15213
412-268-7803
@johnkitchin
http://kitchingroup.cheme.cmu.edu