1

我有一个非常简单的例子来说明这个问题。考虑以下 Perl 中的代码块,位于 org-mode 文件中:

#+begin_src perl :results table
return qw(1 2 3);
#+end_src

它产生以下结果:

#+results:
| 1\n2\n3\n |

这并不完全令人满意,因为我期待一个完整的组织表。

例如,在 Python 中,以下代码:

#+begin_src python :results table
return (1, 2, 3)
#+end_src

产生这个结果:

#+results:
| 1 | 2 | 3 |

所以这显然适用于 Python,但不适用于 Perl。难道我做错了什么?这是一个已知的错误?

4

1 回答 1

3

因为今天早上我觉得有点自虐,所以我决定再次尝试破解一点 lisp。我制作了一个适用于您的示例的小修复程序,但我不能保证它会适用于更复杂的修复程序。所以它来了:

org-babel 为每种语言定义了一个包装器。perl 没有产生 babel 检测为列表的东西,所以我修改了它。为了不将所有内容格式化为表格,我必须检查结果是否可打印为表格:

(setq org-babel-perl-wrapper-method
  "
sub main {
%s
}
@r = main;
open(o, \">%s\");
if ($#r > 0) {
print o \"(\",join(\", \",@r), \")\",\"\\n\"
} else {
print o join(\"\\n\", @r), \"\\n\"
}")

如果您愿意,您可以进一步修改它以满足您的需要。

接下来是perl-evaluatebabel 中的方法不会通过进一步格式化来运行输出,所以我修改了评估方法,从python-evaluate代码中获取新部分:

(defun org-babel-perl-table-or-string (results)
  "Convert RESULTS into an appropriate elisp value.
If the results look like a list or tuple, then convert them into an
Emacs-lisp table, otherwise return the results as a string."
  (org-babel-script-escape results))


(defun org-babel-perl-evaluate (session body &optional result-type)
  "Pass BODY to the Perl process in SESSION.
If RESULT-TYPE equals 'output then return a list of the outputs
of the statements in BODY, if RESULT-TYPE equals 'value then
return the value of the last statement in BODY, as elisp."
  (when session (error "Sessions are not supported for Perl."))

    ((lambda (raw)
     (if (or (member "code" result-params)
         (member "pp" result-params)
         (and (member "output" result-params)
          (not (member "table" result-params))))
     raw
       (org-babel-perl-table-or-string (org-babel-trim raw))))

     (case result-type
       (output (org-babel-eval org-babel-perl-command body))

       (value (let ((tmp-file (org-babel-temp-file "perl-")))
        (org-babel-eval
         org-babel-perl-command
         (format org-babel-perl-wrapper-method body
             (org-babel-process-file-name tmp-file 'noquote)))
        (org-babel-eval-read-file tmp-file))))))

新部分是空行之间的org-babel-perl-table-or-string部分(最后加上 1 个右括号)。org-babel-perl-evaluate

所以现在它所做的就是让 perl 打印列表,类似于 python 打印它们的方式,并将打印的结果通过 org-babel 的格式化程序。


现在到结果:

一个列表:

#+begin_src perl :results value
return qw(1 2 3);
#+end_src

#+results:
| 1 | 2 | 3 |

一个标量:

#+begin_src perl :results value
return "Hello test 123";
#+end_src

#+results:
: Hello test 123

您可以使用此代码的方式:

  1. 将其置于划痕中并M-x eval-buffer进行测试
  2. 将其放在 org-document 开头的 elsip src 块中
  3. 加载 babel 后将其放在 .emacs 中
  4. 修改 lisp/org 文件夹中的 ob-perl.el(可能需要重新编译 org-mode 之后)

我没有比我给你的输出示例做更多的测试,所以如果它对其他示例行为不端,请随时抱怨。

于 2013-02-06T09:18:58.907 回答