在Emacs缓冲区中渲染Markdown

50

是否可以使用Emacs自身的文本格式化功能在Emacs缓冲区中呈现Markdown渲染结果?图形环境下的Emacs具有丰富的文本展示能力(字体样式、颜色、链接甚至图片),因此这应该是完全可能的。是否存在任何现有的实现方式?

请注意,想法是让渲染后的Markdown成为原生的Emacs格式化文本,可以像Emacs中的任何其他文本一样进行导航和操作。因此,以嵌入在Emacs缓冲区中的图像形式呈现的解决方案在此不可取。

同时请注意,这与编辑Markdown的模式无关,而是用于在Emacs缓冲区中呈现Markdown渲染结果。最好是纯Emacs Lisp解决方案,以便实现可移植性。


有任何具体要求吗?就像“markup”不代表HTML一样,“markdown”的含义也很模糊。 - phils
1
Markdown 就像任何 Markdown 方言一样,如果这是你的意思! - Markus Miller
8个回答

22

个人而言,我使用以下工作流程:

  • 运行 C-c C-c m 以在当前缓冲区上运行 Mark­down 并在另一个缓冲区中预览输出。
  • 在该另一个缓冲区上移至 html-modeM-x html-mode
  • 隐藏 HTML 标记以显示接近输出的内容(M-x sgml-tags-invisible

然后,每次您想要刷新渲染时,只需在 Markdown 缓冲区上再次运行 C-c C-c m

但是我承认,就编辑/预览 Markdown 而言,迄今为止 Textmate 和其 markdown 预览面板无与伦比。实际上,从个人角度来看,我唯一喜欢使用 Textmate 而不是 Emacs 的情况是我想编辑 Markdown 文件。然而,要在 Emacs 上拥有相同质量的预览路径并不难,我可能应该进行调查。我认为,它很简单:

  • 获取 Textmate 用于呈现预览的内部 CSS
  • 使用 w3 或 w3m 使用此 CSS 预览 Markdown 输出

谢谢,我喜欢你如何将所有这些功能结合在一起 :) - Ev Dolzhenko
4
安装很好,但是出现了无法刷新的问题。当我在渲染后的缓冲区上运行 C-c C-c m 时,显示 C-c C-c m is undefined;而当我在源代码缓冲区上运行它时,则显示 Text is read-only。我该如何解决这个问题? - Matthew Piziak
你是否在使用 markdown-mode?也许你可以确保你已经安装并更新了 markdown-mode。你也可以运行 C-h k C-c C-c m 来检查 C-c C-c m 是否绑定到函数 markdown-other-window。你也可以直接使用 M-x markdown-other-window 运行 markdown-other-window 函数。 - modulitos
由于已经存在只读缓冲区(在我的情况下被另一个Markdown输出占用),所以我得到了“文本是只读的”错误。删除缓冲区后,该错误消失了。 - user3113626

7

我在我的.emacs文件中有这个:

(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(markdown-header-delimiter-face ((t (:inherit font-lock-function-name-face :underline t :weight bold))) t)
 '(markdown-header-face-1 ((t (:inherit markdown-header-face :height 1.5))) t)
 '(markdown-header-face-2 ((t (:inherit markdown-header-face :height 1.3))) t)
 '(markdown-header-face-3 ((t (:inherit markdown-header-face :underline t :height 1.2))) t)
 '(markdown-header-face-4 ((t (:inherit markdown-header-face :underline t :height 1.1))) t)
 '(markdown-header-face-5 ((t (:inherit markdown-header-face :underline t))) t)
 '(markdown-header-face-6 ((t (:inherit markdown-header-face :underline t))) t))
(put 'set-goal-column 'disabled nil)

这将放大所有标题。Markdown-mode本身会使星号文本变成斜体,双星号文本加粗,所以这样做就可以了。但是,它不会使控制字符不可见。

如果您想要这样做,您应该考虑查看pretty-lambda的示例(正如Bozhidar Batsov建议的那样)。


7
我猜你可以使用latex-preview的源代码来获得启发,或者pretty-lambda(一个更简单的软件)。

或者,您可以在后台进程中将Markdown转换为HTML并预览HTML。

Emacs可以实现任何事情,但不是所有事情都容易实现 :-)


1
感谢提到latex-preview。然而,我不想将Markdown渲染为嵌入在Emacs缓冲区中的图像,而是希望它作为本地的Emacs格式化文本,可以像其他文本一样进行导航和操作。也许可以从pretty-lambda中学到一些东西。 - Markus Miller

5

根据您想要查看呈现文本的上下文,您可能只需调整markdown-mode的字体锁定规则就可以接近所需效果。


听起来是一种实用的方法,只需要小小的努力(更新字体锁定规则),而且不依赖于任何外部工具或过程,这很好。 - Markus Miller

4
除了已经被建议多次的pretty-lambda外,您还可以查看org-mode及其语法高亮规则。特别是org-hide-emphasis-markers变量实现了您想要的功能(例如,请参见org-do-emphasis-faces如何隐藏标记字符)。

3

由于我不知道任何基于emacs的Markdown解析器,所以我必须说你需要从头开始编写一个。也许这个SO问题可以给你一些指引。

如果您选择走Emacs-only的路线,那么Semantic是这项工作的优秀API(它为您提供了词法分析器、解析器生成器和解析器;它已经存在了十多年,并且有文档!)。在拥有语言解析器之后,您将需要为每种令牌类型制作一些渲染函数。通过这种方式,您可以自定义一切。

虽然这肯定是一次启发性的旅程,但我仍然选择在单独的后台进程上使用现有的Markdown->html转换器,然后使用w3(m)进行emacs预览(正如Bozhidar所建议的那样)。它能完成任务,而且更简单。没有主要的性能问题——您应该很少运行此工具,因此可以轻松地节省一些额外的毫秒数)。

混合解决方案是使Markdown解析器直接生成HTML,并在w3(m)缓冲区中预览它(它将渲染负担从您的肩膀上卸下,您只需要将Markdown转换为html,并且使用Semantic似乎相当简单)。


感谢您提供有关解析Markdown的问题以及提到Semantic的链接。 - Markus Miller

1
如果只是关于渲染,可以采用Bozhidar的建议,进行Markdown到HTML转换,然后在W3缓冲区中显示HTML。 markdown-mode有一些代码可以调用外部Markdown命令,并提供一些好处。
但是,如果你真的想在Emacs Lisp中完成所有操作,你首先需要编写一个Markdown解析器。

1
谢谢,但我真的想将所有内容都用 Emacs Lisp 编写,以便实现可移植性。因此,我希望能找到一个现成的 Emacs Lisp Markdown 解析器。 - Markus Miller

0

我也是,我已经寻找了很长时间类似的东西。但是我能找到的最好的解决方案并不是Emacs,而是一款独立的优秀软件ReText


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接