将Org-mode文件导出为HTML后出现意外的链接行为

时间:2014-09-16 21:15:12

标签: html emacs org-mode

我在Windows 7旗舰版的Emacs 24.3.1中运行Org-mode 8.2.6,并且遇到了从Org-mode导出的HTML链接如何工作的特殊性。我已广泛使用org-id为组织模式文件中的标题分配唯一ID(存储在标题的:PROPERTIES:抽屉中)。

在Org-mode 8.0中引入新的导出器框架之前,所有这些链接都没有问题。无论标题层次结构的级别如何,导出的基于HTML ID的链接都可以正常工作。但是,使用新的导出器框架会产生不同的结果。现在,当目标标题位于导出设置中定义的标题级别以下的级别时,基于ID的链接始终会失败,默认为级别3(H:3)。注意:这仅适用于导出的HTML;基于身份的链接在Emacs中完美运行。

这是一个最小的示例,演示了当我将其导出为HTML时的这种行为(有关详细信息,请参阅注释):

* Headline Level 1
** Headline Level 2
*** Headline Level 3
:PROPERTIES:
:ID:       307db49e-e001-4a7b-9541-96eee2ae6f06
:END:
**** <<heading-level-4>>Non-headline level
:PROPERTIES:
:ID:       3be9179d-f838-4052-93ca-6c76c9aff12d
:END:
** Headline Level 2
*** Headline Level 3
Now I want to link to information that appears elsewhere in the file. Links work as 
expected within Emacs. When exported to HTML, however, links do not work as they 
did before the new exporter framework was introduced in Org-mode 8.0.
**** ID-based link: [[id:307db49e-e001-4a7b-9541-96eee2ae6f06][Headline Level 3]]
This link /does/ work. Using IDs always works for links to any headline level. By 
"headline level" I mean any Org-mode heading that is defined as a headline 
(default H:3).
**** ID-based link: [[id:3be9179d-f838-4052-93ca-6c76c9aff12d][Non-headline level]]
This link using the ID /doesn't/ work when exported to HTML using the new exporter 
framework. Now, using IDs as the target for links /always/ fails for links to any 
headline lower than the headline level defined in the export settings.
**** Non-ID-based link: [[heading-level-4][Non-headline level]]
Using an internal link works, but I have /many/ existing files that depend on IDs 
for links at heading levels lower than the levels I want treated as (numbered) 
headlines, and I also sometimes link to targets in other files, in which case, 
using ID's creates a much simpler workflow.

如果上面的文件名为demo-links.org,则默认输出文件为demo-links.html。第一个工作链接的目标的HTML如下所示:

<h4 id="sec-1-1-1"><a id="ID-307db49e-e001-4a7b-9541-96eee2ae6f06" name="ID-307db49e-e001-4a7b-9541-96eee2ae6f06"></a><span class="section-number-4">1.1.1</span> Headline Level 3</h4>

并且指向它的链接的HTML如下所示:

<a href="#sec-1-1-1">Headline Level 3</a>

链接ID是目标代码的一部分,但未在链接代码中使用。

非工作链接目标的HTML如下所示:

<ul class="org-ul"><li><a id="heading-level-4" name="heading-level-4"></a>Non-headline level<br /><div class="outline-text-5" id="text-1-1-1-1"></div></li></ul>

请注意,生成的代码不包含ID(3be9179d-f838-4052-93ca-6c76c9aff12d)。它也不包含像上一个链接那样的节ID。

指向它的链接的HTML如下所示:

<a href="#sec-1-1-1-1">Non-headline level</a>

我认为ox-html.el中的相关代码出现在评论“指向标题的链接”之后,但我是elisp的新手(充其量)。

我的问题是:这个行为是设计的,还是有一些我可以改变的设置会使导出工作的方式与引入新的导出框架之前的方式相同?

2 个答案:

答案 0 :(得分:1)

我也遇到了这个问题。更重要的是,“&lt;&lt;”之间的文字和“&gt;&gt;”可以在org-7.9中导出的HTML中显示,但无法在org-8.2中显示

由于声誉有限,我无法对该项目进行投票,所以我只是在没有正确答案的情况下回答它。 (= _ =)

答案 1 :(得分:0)

查看org-html-headline函数的代码,似乎“标准标题”案例(导出到hN的任何内容)特别是处理自定义ID:

(let* (...
       (ids (remove nil
                    (list (org-element-property :CUSTOM_ID headline)
                          (concat "sec-" section-number)
                          (org-element-property :ID headline))))
       (preferred-id (car ids)) ;; <- here, id for the header is sec-XXX
       (extra-ids (cdr ids))
       ...)
  (format ...
          (format "outline-container-%s"
                  (or (org-element-property :CUSTOM_ID headline)
                      (concat "sec-" section-number)))
          ...
          (format "\n<h%d id=\"%s\">%s%s</h%d>\n"
                  level1
                  preferred-id
                  (mapconcat
                   (lambda (x)
                     (let ((id (org-export-solidify-link-text
                                (if (org-uuidgen-p x) (concat "ID-" x)
                                  x))))
                       (org-html--anchor id))) ;; <- generate a list of <a id=ID-XXX></a>
                   extra-ids "")
                  full-text
                  level1)
          ...))

那些<a id="ID-XXX" name="ID-XXX"></a>片段来自哪里(占位符锚点,只是为了公开额外的ID)

不幸的是,在标题转换为列表项的情况下,没有ID / CUSTOM_ID的这种处理,这对我来说非常坦率地说是一个错误。 因此,尽管可以重写org-html-headline对列表项执行相同的处理,但遗憾的是它不像修改设置那么容易(并且代码修改会非常脆弱)

我建议打开一个错误报告,毕竟它似乎是一个回归。