ljos / jq-mode

Emacs major mode for editing jq queries.
GNU General Public License v3.0
110 stars 12 forks source link

Make ob-jq aware of org-tables (input and output) #10

Closed Fuco1 closed 6 years ago

Fuco1 commented 6 years ago

A table formated as such

foo bar
a b
c d

can serve as an input json which is an array with foo and bar being keys and a,b and c,d respective values.

The keyword for this is :table <reference>

Fuco1 commented 6 years ago

We could probably make the :stdin option smart enough to detect if the reference is a block with text or a table... that would be another option to do this but maybe less explicit and more magical (although it has a certain coolness to it...). What do you think about such an option?

Also the output code seems a bit peculiar to me so I've changed it a bit, was there any reason behind the previous implementation?

Fuco1 commented 6 years ago

I've also noticed I've introduced a dependency on json-mode for the result pretty-print... I think jq can do that by default so I'll try to fix that too.

ljos commented 6 years ago

As I understand it, there is good precedent for making the input a bit magic in org-babel; I think the smart :stdin is a good addition.

The whitespace fix is fine, but would you mind merging the other commits after fixing the hard dependency on json-mode?

Fuco1 commented 6 years ago

Agreed on the magic, it always works in a "do what I want" manner so I think we should keep at it.

By merge you mean squashing the commits? Sure, I'll do that, I accidentaly introduced some dependencies on my local config anyway :D

ljos commented 6 years ago

Yes. I mean squashing them together. Thank you for working on this.

Fuco1 commented 6 years ago

@ljos I've squashed the two commits adding the input support.

I've also extended the output so that with :results table it will try to reasonably guess if the output json is interpretable as a table and do that.

If it is a vector of (homogenous, assumed) objects, grab the keys as column names and generate a table. If it is a vector of vectors just unpack the data into a table. Otherwise print the result even if :results table is set as we can't guess what to do.

I've set the default to :results output so that without any special directives it always prints the output as recieved from jq (which also pretty prints it)

ljos commented 6 years ago

I am happy to merge this after you add the (t res) clause to the cond in org-babel-execute:jq.

Fuco1 commented 6 years ago

@ljos I've fixed the cond and also added a catch-all clause for the table output: if it's not a vector of vectors or lists just pass the output (which is probably an array), such that

#+NAME: foo
#+BEGIN_EXAMPLE
[1,2,3,4]
#+END_EXAMPLE

#+BEGIN_SRC jq :stdin foo :results table
.
#+END_SRC

#+RESULTS:
: [1 2 3 4]

still works at least somehow. It could alternatively produce a table of one row.

Fuco1 commented 6 years ago

Yea, I went ahead with that and just make it a table:

#+NAME: foo
#+BEGIN_EXAMPLE
[1,2,3,4]
#+END_EXAMPLE

#+BEGIN_SRC jq :stdin foo :results table
.
#+END_SRC

#+RESULTS:
| 1 | 2 | 3 | 4 |
ljos commented 6 years ago

Thank you very much for working on this! I added you as a collaborator so you can make changes in the future or fix bugs without asking if you need to. You don't have to accept if you don't feel like it or have other things you would rather spend time on.

Fuco1 commented 6 years ago

Cool! I'll probably run things through PRs anyway as it's good to have more eyes on the changes (except for the trivial fixes like typos etc).

ljos commented 6 years ago

I think that is a good idea. Thanks for contributing!