Skip to content

p-baleine/jq.el

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jq.el.

https://github.com/p-baleine/jq.el/workflows/CI/badge.svg?branch=master

Decription

Emacs Lisp bindings for jq.

Usage

(require 'jq)

(let ((input "
[
  {
    \"name\": \"Ness\",
    \"age\": 12,
    \"origin\": { \"country\": \"Eagleland\", \"town\": \"Onett\" }
  },
  {
    \"name\": \"Paula\",
    \"age\": 11,
    \"origin\": { \"country\": \"Eagleland\", \"town\": \"Twoson\" }
  }
]
"))
  (cl-loop for x iter-by (jq input ".[] | .origin.town") collect x))

;;=> ("Onett" "Twoson")

Motivation

Recently I wanted an API client for Emacs which communicate with a RESTful server. I read documents and code of the RESTful server and designed the API client naively by calling the server with curl and jq.

Then, when I would implement the designed client on Emacs Lisp, I remembered that it is a bother to parse JSON strings on Emacs Lisp and I would have to call the server multiple times to implement the client.

Emacs Lisp includes json.el and can parse JSON strings but the results are association lists, so if the fields I am interested in are placed deeply inner the code to retrieve the fields would be very complicated.

Below is a sample where I would want origin.town of each element from a JSON string input.

(let* ((input "
[
  {
    \"name\": \"Ness\",
    \"age\": 12,
    \"origin\": { \"country\": \"Eagleland\", \"town\": \"Onett\" }
  },
  {
    \"name\": \"Paula\",
    \"age\": 11,
    \"origin\": { \"country\": \"Eagleland\", \"town\": \"Twoson\" }
  }
]
")
       (parsed (json-read-from-string input)))
  (cl-loop for entry across parsed
    collect (let* ((origin (cdr (assoc 'origin entry)))
                   (town (cdr (assoc 'town origin))))
              town)))

;;=> ("Onett" "Twoson")

If my interested fields are placed more deeply inner, the program would be more complicated.

Why I cannot retrieve interested fields of JSON string as simple as the design phase where I could use curl and jq?

This is the motivation that drives me to implement jq.el. With jq.el, we can rewrite the above program as below.

(let ((input "
[
  {
    \"name\": \"Ness\",
    \"age\": 12,
    \"origin\": { \"country\": \"Eagleland\", \"town\": \"Onett\" }
  },
  {
    \"name\": \"Paula\",
    \"age\": 11,
    \"origin\": { \"country\": \"Eagleland\", \"town\": \"Twoson\" }
  }
]
"))
  (cl-loop for x iter-by (jq input ".[] | .origin.town") collect x))

;;=> ("Onett" "Twoson")

Getting Started

Prerequisites

cmake
>= 3.10.0
other build dependencies
oniguruma headers, gcc, gcc-c++, libtool, autoconf, yacc & lex and git

To install all build dependencies on Ubuntu, use:

apt install cmake build-essential autoconf libtool bison flex

On Fedora, use:

dnf install cmake make gcc gcc-c++ autoconf libtool bison flex

Building

mkdir build
cd build
cmake ..
cmake --build .

Installing

Add the following code to ~/.config/doom/packages.el.

(package! jq
  :recipe (:local-repo "/path/to/jq.el"
            :files (
              "*.el"
              "build/jq-impl.so")))

Add the following code to dotspacemacs-additional-packages of ~/.spacemacs.

dotspacemacs-additional-packages
'(
  ;; ...
  (jq.el :location "/path/to/jq.el/jq.el")
  (jq-impl.el :location "/path/to/jq.el/build/jq-impl.el")
  )

Add the following code to ~/.init.el.

(require 'package)

(package-install-file "/path/to/jq.el/jq.el")
(package-install-file "/path/to/jq.el/build/jq-impl.el")

API

jq (input program)

Return results of executing jq by passing input and program as arguments.

Development

Running tests

emacs -Q --batch -L build -f batch-byte-compile jq.el \
  && emacs -Q --batch -L build -L . -l test/jq-test.el -f ert-run-tests-batch-and-exit

Acknowledgments

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

About

Emacs Lisp bindings for jq.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published