org模式-在Perl中有一个表作为org.babel代码块的结果



我有一个非常简单的例子来说明这个问题。在组织模式文件中,考虑Perl中的以下代码块:

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

它产生以下结果:

#+results:
| 1n2n3n |

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

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

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

产生以下结果:

#+results:
| 1 | 2 | 3 |

因此,这显然在Python中有效,但在Perl中无效。我做错什么了吗?这是一个已知的bug吗?

由于今天早上我觉得有点受虐,我决定再次尝试破解口齿不清的问题。我做了一个小的修正,适用于你的例子,但我不能保证它会适用于更复杂的例子。所以它来了:

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"
}")

如果你想的话,你可以进一步修改以满足你的需求。

接下来的事情是babel中的perl-evaluate方法没有通过进一步的格式化来运行输出,所以我修改了评估方法,从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和位于空行之间的org-babel-perl-evaluate中的部分(加上末尾的1个右括号)。

因此,现在所做的是让perl打印列表,类似于python打印列表的方式,并通过org.babel的格式化过程来打印结果。


现在来看结果:

A列表:

#+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. 将它放在组织文档开头的elsip src块中
  3. 加载babel后将其放在你的.emacs中
  4. 在您的lisp/org文件夹中修改ob-perl.el(以后可能需要重新编译组织模式)

我没有比我给你的输出示例做更多的测试,所以如果它在其他示例中表现不佳,请随意抱怨。

最新更新