What is the best YAML parser in elisp?
Asked Answered
T

5

16

I want to read config in YAML with elisp code. Searched but didn't find ready-to-use parser in elisp. Did I miss something useful?

Thankyou answered 10/4, 2012 at 17:9 Comment(4)
I don't know the answer, but if there isn't any then you can call some other parser to read the yaml and have it output a textual lisp representation which you can read with read.Dvina
Thanks! It's a good idea. Maybe I can try pymacs.Thankyou
I'm not sure what you mean - there is a yaml-mode here: github.com/yoshiki/yaml-mode - but you want a parser to read the yaml and do what with it?Paralipomena
I want to read some configuration from YAML files.Thankyou
O
10

Three years later, we have dynamic modules, and emacs-libyaml looks pretty interesting. It uses the dynamic module system to expose the C bindings of libyaml in Elisp. I would expect the performance to be fantastic, although I haven't tested it.

Oxytocin answered 14/9, 2017 at 1:35 Comment(0)
G
5

Six months later, it appears that the answer is "there exists no solid easily-available elisp YAML parser."

If you really want to read a YAML document in elisp and turn it into something that elisp can interact with, you're going to have to put in some gnarly work. The EmacsWiki YAML page hasn't got much for you, and the canonical YAML mode has syntax hints, but no actual parser. Fortunately someone has implemented a YAML-parsing web-app that takes YAML and outputs JSON or Python - you could try to get a look under the hood of that and-or use it to check any YAML parser you may write yourself.

Good luck.

Goral answered 16/10, 2012 at 18:12 Comment(2)
Addendum: see this SO answer for some getting-started code when writing one's own recursive-descent parser in elisp.Goral
edward.oconnor.cx/2006/03/json.el might also be useful for comparison and ideas. Obviously, YAML is not JSON, but they certainly have some similarities.Modify
T
5

And some months later: I wanted it, so here's how to do it with some help from python:

   (defun yaml-parse ()
  "yaml to json to a hashmap of current buffer, with python.

   There is no yaml parser in elisp.
   You need pyYaml and some yaml datatypes like dates are not supported by json."
  (interactive)
  (let ((json-object-type 'hash-table))
    (setq  myyaml (json-read-from-string (shell-command-to-string (concat "python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)' < " (buffer-file-name))))))
  ;; code here
  )

It turns the yaml of the current buffer into an elisp hashmap, with the help of json.el.

You need python's pyyaml: pip install PyYaml.

json.el: http://edward.oconnor.cx/2006/03/json.el

Tundra answered 7/8, 2014 at 14:25 Comment(1)
I mean on one level that's a hack that makes me wince, but on another, I can't bring myself to disrespect "the tool I need doesn't exist, so I'll write it myself." Upvoted.Goral
C
3

Three more years later, I'm happy to say that there is now a YAML parser written in Elisp: https://melpa.org/#/yaml

It's API is similar to that of json-parse-string in that you can specify it's object and list type. The following is an example of its usage:

(yaml-parse-string "
-
  \"flow in block\"
- >
 Block scalar
- !!map # Block collection
  foo : bar" :object-type 'alist)
;; => ["flow in block" "Block scalar\n" (("foo" . "bar"))]
Cirrhosis answered 26/3, 2021 at 5:6 Comment(0)
B
2

To improve on Ehvince answer using python, a more generic way that allows parsing string, buffers and files:

(defun yaml-parse (string)
  "yaml STRING to json to a hashmap of current buffer, with python."
  (interactive)
  (with-temp-buffer
    (insert string)
    (when (zerop (call-process-region (point-min) (point-max) "python" t t nil "-c" "import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout)"))
      (goto-char (point-min))
      (json-read))))

(defun yaml-parse-buffer (&optional buffer)
  "Parse yaml BUFFER."
  (with-current-buffer (or buffer (current-buffer))
    (yaml-parse (buffer-substring-no-properties (point-min) (point-max)))))

(defun yaml-parse-file (file)
  "Parse yaml FILE."
  (with-temp-buffer
    (insert-file-contents-literally file)
    (yaml-parse (buffer-substring-no-properties (point-min) (point-max)))))

You can use the json-* variables to control type mappings.

edit: Added yaml-parse-file

Bessiebessy answered 2/12, 2019 at 11:17 Comment(3)
Trying to use this with a sample yaml file from a symfony project, ix.io/2emU/yaml. No go. Debugger entered--Lisp error: (json-number-format 2) signal(json-number-format (2)) json-read-number(t) json-read-number() json-read()Esta
@RichieHH: that yaml doesn't look valid to me. What are those \: ?Bessiebessy
part of the key which is a path. Im no expert. YAML files that ship with symfony bundles.Esta

© 2022 - 2024 — McMap. All rights reserved.