我想用 elisp 代码读取 YAML 中的配置。搜索但未在 elisp 中找到现成的解析器。我错过了什么有用的东西吗?
5 回答
三年后,我们有了动态模块,emacs-libyaml看起来很有趣。它使用动态模块系统在 Elisp中公开libyaml的 C 绑定。我希望性能会很棒,尽管我还没有测试过。
几个月后:我想要它,所以这里是如何在 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
)
它在json.el
.
你需要 python 的 pyyaml: pip install PyYaml
。
六个月后,答案似乎是“不存在可靠且易于使用的 elisp YAML 解析器”。
如果您真的想在 elisp 中读取 YAML 文档并将其转换为可以与 elisp 交互的内容,您将不得不进行一些繁琐的工作。EmacsWiki YAML 页面没有给你太多,规范的YAML 模式有语法提示,但没有实际的解析器。幸运的是,有人已经实现了一个 YAML 解析网络应用程序,它接受 YAML 并输出 JSON 或 Python——你可以尝试看看它的底层,或者使用它来检查你自己编写的任何 YAML 解析器。
祝你好运。
又过了三年,我很高兴地说现在有一个用 Elisp 编写的 YAML 解析器:https ://melpa.org/#/yaml
它的 API 与 类似json-parse-string
,您可以指定它的对象和列表类型。以下是它的用法示例:
(yaml-parse-string "
-
\"flow in block\"
- >
Block scalar
- !!map # Block collection
foo : bar" :object-type 'alist)
;; => ["flow in block" "Block scalar\n" (("foo" . "bar"))]
为了改进使用 python 的 Ehvince 答案,一种更通用的方法,允许解析字符串、缓冲区和文件:
(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)))))
您可以使用 json-* 变量来控制类型映射。
编辑:添加 yaml-parse-file