重新思考了一下 orgmode 文学编程

使用了一段文学编程以后,发现我很难适应这种工作方式,主要问题有以下几点:

  1. 当代码块比较长时,会冲淡正文内容,我的代码主要是一些 python 做图代码,有的会很长。当文档中很多这种长的代码块后,视觉上给人一种杂乱感。作为一个强迫症患者,我自认处理不了这种复杂情形,因而会焦虑。即使折叠代码块,这种感觉也不会消失。而且,当屏幕分辨率较小时,翻页时经常会有代码块占据整个屏幕的情况,浏览正文内容也不太方便。

  2. 行内图形的显示问题,org 的行内图形显示无法自动缩放图像,虽然 scimax 添加了图形缩放,但是以我用的情况来说,感觉并不理想,很笨重,而且有 bug。

  3. scimax 曾经是我文学编程的理由,但是现在已经无力使用了,主要问题是 bug 太多,最近 kitchin 做了大的更新,但是我无意追随。现在宁愿在 jupyter notebook 配合各种插件来编辑。我现在需要的是设置 org 链接,点击链接直接打开 notebook。

暂时想到以上几点,想到再添加。欢迎大家吐槽。总之,就是代码块虽好,但不能滥用,不然会适得其反

我现在的想法是,将做图代码用单独文件,然后在 org 中添加文件链接,导出的时候检查做图文件相同的文件夹内是否有图形,没有就执行这个文件,并将得到的图形加入到导出的文件中,如果有就不执行代码,直接替换链接为图片。不知道大家对此有何看法?

作為原教旨主義者我表示你会这麼想是因為用的不是正宗的文学编程。

一個正确用法的示例

真正的文学编程除了正文外,会根据 logic flow 用 TAG 來拆分代码块。比如下图,在写 prime_the_change_buffer 的時候,Knuth 沒有一股脑把定义都写出來,而是继续分成三部分,就各个部分单獨说明。

这个功能在 Org 中也有。应該说是个文学编程就會支持。

In the Org-mode file:

#+name: hello-world-prefix
#+begin_src sh :exports none
  echo "/-----------------------------------------------------------\\"
#+end_src

#+name: hello-world-postfix
#+begin_src sh :exports none
  echo "\-----------------------------------------------------------/"
#+end_src

#+name: hello-world
#+begin_src sh :tangle hello :exports none :noweb yes
  <<hello-world-prefix>>
  echo "|                       hello world                         |"
  <<hello-world-postfix>>
#+end_src

Calling org-babel-tangle will result in the following shell source code being written to the hello.sh file:

#!/usr/bin/env sh

# [[file:~/org/temp/index.org::*Noweb%20test][hello-world]]

echo "/-----------------------------------------------------------\\"
echo "|                       hello world                         |"
echo "\-----------------------------------------------------------/"
# hello-world ends here

https://orgmode.org/worg/org-contrib/babel/intro.html

这个能滿足你的需求嗎?

对 Python 來說,Jupyter 是挺好的。

7 个赞

对我等小白来说,文学编程还是过于重度了。而且对我来说,文学编程就基本上等于 org-babel。

我一直用的帖子里的 kitchen 的代码,但是感觉还是麻烦,而且我碰到过缩放不正确的情况(打开文件后,图片超级小),我想要的是根据指定宽度(以及高度),自动缩放,如果图片没到制定宽度,就按原来的大小显示。总之就是更加智能。有点像word中的图片的感觉。

我既不会文学,也不会编程,对我来说 noweb 就像一个玩具一样。目前的 Org noweb 还有局限性,对 S-exp 系不太友好(可能是 feature 吧)。

有没有试过这些命令:

  • org-babel-goto-named-src-block
  • org-babel-goto-named-result
  • org-babel-goto-src-block-head

这些命令的前提都是必须记住代码块的名字,代码块多的时候不现实,或者已有 ivy 支持?

默认是用 completing-read,装了 ivy 就能补全了。

跳转完成后可以用 org-mark-ring-goto 返回。

1 个赞

这样好一点,但是仍然有点笨重

如果fold所有代码块 并且只用org-edit-special来编辑呢?

个人没有详细了解过「文学编程」这个古老(或新潮?)的概念在试图解决什么问题,但 Jupyter 的表现已经足够令我满意。除 Python 外,它还支持其它内核(这也是当时我的静态博客选 Nikola 的原因之一)。

今天只要你有需求,稍微折腾下,就能在博客上分享 R、Go、JavaScript 等代码及执行结果,甚至还能加上可互动的控件。

又或许,楼主你的关注点是 如何使用 Emacs 实现 ?唔……

  1. 代码块太长的问题。不太可能说,你分享的代码每一行都很重要,肯定有层级有重点。太长的不重要的,可以封装下扔到另一个文件里,然后再 import 进来。

    另外,可以研究下 Emacs 的自定义折叠功能。代码块内超过多少行后自动折叠,相信是可以做到的。如果能用 JavaScript 对博客文章也做相同处理,那就更好了。就是比较折腾,要求对 Emacs 和 elisp 有相当程度的了解。

  2. 行内图片显示问题。达到 word 中图片那样,随窗口调整大小而变化。这个一定程度上可以实现的(Emacs 应该有 resize 窗口事件?)。但资源消耗肯定很大,因为要不停地调用 imagemagick 缩放图片。

    没到指定宽度,就按原来大小显示。应该也是可以的。imagemagick 本身是支持的。比如设定图片高宽:100x200> 。代表仅高度超过 100px,或者宽度超过 200px 时,才缩小图片(否则,保持原样不动)。不过,我还没有在 Emacs 里试过,你可以自己试一下。

    imagemagick 参考:Image Geometry

1 个赞

最近折腾了下org的html的导出, 这个用js是可以实现的

Demo: https://htmlpreview.github.io/?https://raw.githubusercontent.com/fuxialexander/doom-emacs/html_style/modules/lang/org/%2Bskyle.html

3 个赞

To keep my sanity, 我还是把绘图代码单独放文件吧,代码块只用来放一些短的操作型代码。实在是忍受不了文字,代码,运行结果,还有代码块的分界行混杂在一起一团糟的感觉了。尤其是有的时候文字很短,甚至还不如代码的注释长,这时候真是丑陋无比。

这个手风琴效果确实简单省事 :+1:

前端框架要和我一样,用 semantic-ui 就更好了!:laughing:

搞生物的玩编程都是这么牛逼的吗?

哈哈 我从stack overflow上抄了段 elisp, 直接从文件里读js和stylesheet然后写入org-html-head.所以要换框架的话改一下js文件里的代码就行了。下回试试semantic UI (有demo/好的插件之类的求分享~

噗 我做生物信息学的 算半个CS吧 demo里那个table只是随手在Google上找的😂

随窗口调整图片大小确实太复杂了,但是 word 里好像也不是这么干的?只要根据宽度调整大小就行了,比如80个字符

也许写 python 的话,这个才是答案:

abo-abo 在 reddit 上说,经过几个月的使用,他认为已经很稳定了,虽然还没有正式发布

这是嵌入在 python 模式中的 orgmode,可以替换 ipython notebook,明天试一下

2 个赞

对,楼主这个不是 纯粹的literal programming.

orgmode的 literal programming 我觉得问题是,各种源代码相关插件都不支持noweb,非常头疼。

jupyter在文件大了以后太慢太卡,极其浪费系统资源,早已放弃,完全不如orgmode。图片很多时候没必要 inline 显示,可以直接链接再单独窗口打开看。

除非像 Haskell 那樣原生对 LP 支持好的,不然 LP 还是要语言专用的工具好一点。

word 肯定不是这么干的呀。我的意思是「想要调整窗口时,图片大小也跟着变化」,这个理论上是能做到的(就是太粗暴,消耗大)。

我用 Emacs 尝试了下,只找到 #+attr_org: :width 100 这样的语法。试了 #+attr_org: :width 100x200> 这样的,发现并不起作用。也没有找到类似 #+attr_org: :geometry 100x200> 这样的属性设置,所以恐怕只能往上游一步,去直接修改 org-mode。


或者,在你 Python 代码块下方再增加一个 Bash 代码块,这样就能使用 imagemagick 的所有功能了,裁剪、阴影、边框、水墨画等等,相当于命令行版的 Photoshop。处理完图片后,再在下方把行内图片显示出来。

1 个赞