在 Emacs 缓冲区中渲染 Markdown

Posted

技术标签:

【中文标题】在 Emacs 缓冲区中渲染 Markdown【英文标题】:Render Markdown in Emacs buffer 【发布时间】:2011-03-25 11:32:56 【问题描述】:

是否可以使用 Emacs 自己的缓冲区文本格式化功能在 Emacs 缓冲区中呈现 Markdown?图形环境中的 Emacs 具有丰富的文本表示功能(字体样式、颜色、链接甚至图像),因此应该很有可能。有没有现成的实现?

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

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

【问题讨论】:

有什么具体要求吗?正如“markup”并不意味着 html,“markdown”也相当模糊。 Markdown 就像在任何 Markdown 方言中一样,如果这就是你的意思! 【参考方案1】:

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

C-c C-c m 上运行以在当前缓冲区上运行 Markdown 并在另一个缓冲区中预览输出。 移动到另一个缓冲区上的html-mode (M-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 的降价输出

【讨论】:

谢谢,喜欢你如何结合所有这些功能:) 很好的设置,但由于某种原因我无法刷新。当我在渲染缓冲区上运行C-c C-c m 时,我得到C-c C-c m is undefined,当我在源缓冲区上运行它时,我得到Text is read-only。我该如何解决这个问题? 你在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 函数。 我得到 Text is read-only 因为已经有一个只读缓冲区(在我的情况下被另一个 markdonw 输出占用)。删除缓冲区后,抱怨消失了。【参考方案2】:

我想您可以使用latex-preview 的源代码或pretty-lambda(一个更简单的软件)的源代码。

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

在 Emacs 中一切皆有可能,但并非一切都可以轻松实现 :-)

【讨论】:

感谢您提及乳胶预览。但是,我不希望将 Markdown 呈现为嵌入在 Emacs 缓冲区中的图像,而是呈现为可以像任何其他文本一样导航和操作的原生 Emacs 格式化文本。不过,也许可以从 pretty-lambda 中学到一些东西。【参考方案3】:

我的 .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 suggested)

【讨论】:

【参考方案4】:

根据您希望查看渲染文本的上下文,您可以通过调整 markdown-mode 的字体锁定规则来获得非常接近所需的内容。

【讨论】:

听起来是一种实用的方法,只需很少的努力(只是更新字体锁定规则),它不依赖于任何好的外部工具或流程。【参考方案5】:

除了pretty-lambda(已经被多次建议),您可以查看org-mode 及其语法高亮规则。特别是,org-hide-emphasis-markers 变量或多或少可以满足您的需求(参见例如 org-do-emphasis-faces 如何隐藏标记字符)。

【讨论】:

【参考方案6】:

由于我不了解任何基于 emacs 的 Markdown 解析器,我不得不说您必须从头开始编写代码。也许this SO question 可以给你一些建议。

如果您选择只走 Emacs 之路,那么 Semantic 是该工作的绝佳 API(它为您提供了词法分析器、解析器生成器和解析器;它已经存在了十多年,并且它有文档!)。拥有语言解析器后,您必须为每种标记类型创建一些呈现函数。通过这种方式,您可以自定义所有内容。

虽然这将是一次启蒙之旅,但可以肯定的是,我仍然会选择在单独的后台进程上使用现有的 Markdown->html 转换器,然后使用 w3(m) 进行 emacs 预览(正如 Bozhidar 建议的那样)。它完成了工作,而且做起来要简单得多。也没有重大的性能问题 - 您应该很少运行这个工具,这样您就可以轻松地节省一些额外的毫秒数)。

一个混合的解决方案是让 Markdown 解析器直接生成 HTML,并在 w3(m) 缓冲区上预览它(它减轻了你肩上的渲染重量,你只需要将 Markdown 音译成 html,然后使用语义似乎很简单)。

【讨论】:

感谢您提供有关解析 Markdown 问题的链接,以及提及语义。【参考方案7】:

如果只是关于渲染,请按照 Bozhidar 的建议进行 Markdown 到 HTML 的转换,然后在 W3 缓冲区中显示 HTML。 markdown-mode 有代码调用外部 Markdown 命令和一些好东西。

但如果你真的想在 Emacs Lisp 中做所有事情,你必须先编写一个 Markdown 解析器。

【讨论】:

谢谢,但我真的很想把它全部放在 Emacs Lisp 中以实现可移植性。因此,我希望找到一个现有的 Emacs Lisp Markdown 解析器。【参考方案8】:

我也是,我一直在寻找类似的东西非常很长时间了。不过,我能找到的最好的不是 Emacs 解决方案,它是一个独立的优秀软件,名为 ReText。

【讨论】:

以上是关于在 Emacs 缓冲区中渲染 Markdown的主要内容,如果未能解决你的问题,请参考以下文章

在 Emacs 中杀死缓冲区时“区分、保存或杀死”

5.Emacs快速入门之缓冲区

emacs 列表缓冲区行为

在 Emacs 中,如何根据缓冲区名称自动启用次要模式?

如何在emacs中自动关闭自动加密模式缓冲区?

关闭 Emacs 中除当前缓冲区之外的所有缓冲区