Given a test.org file like

* A level one heading
** [[file:other.org*some_heading][Some good stuffs]]

If I export it to HTML, Some good stuffs can get a nice link to another HTML. But this is not the case when exporting to PDF.

So when exporting to PDF, I want to include the actual content of some_heading. I know I can use something like

#+INCLUDE: "other.org*some_heading"

But that's a comment, and it's not easy for me to see the origin structure of test.org. I want it at least look like a heading in the org file.

Is there a way to keep Some good stuffs a link when exporting to HTML while include its actual content when exporting to PDF? Thanks.

  • The link syntax is wrong: it should be [[file:other.org::*some_heading][Some good stuff]]. When I export to PDF and open it with xpdf, Some good stuff is a link: when clicked, it opens other.org, although it does not go to some_heading. I'm not sure whether that behavior requires some setting in xpdf, but looking at both the global and local xpdfrc file, I find nothing relevant.
    – NickD
    Apr 14, 2020 at 16:23
  • @NickD I've fixed the link syntax! When I export it to PDF on my mac, none the the PDF readers can follow the link to a org file or another PDF file. Apr 15, 2020 at 1:50

1 Answer 1


I finally come up with this solution, if you have better solution please post your answers!

(defun org-count-skip-lines-before-heading (filename)
    (insert-file-contents-literally filename)
    (goto-char (point-min))
    (let ((count 0))
      (while (and (< (line-end-position) (point-max))
                  (not (string-match "^[ ]*\\*+" (thing-at-point 'line))))
        (incf count)
      (if (>= (line-end-position) (point-max))
          (incf count))

(defvar-local org-export-to-latex-follow-heading-link t)
(defun org-export-to-latex-include-linked-headings (backend)
  (when (and (org-export-derived-backend-p backend 'latex)
     (lambda ()
       ;; If current heading has no content.
       (unless (org-element-property :contents-begin (org-element-at-point))
         (let ((text (nth 4 (org-heading-components))))
           ;; If current heading is a org link.
           (if (string-match org-bracket-link-regexp text)
               (let ((location (match-string 1 text))
                     (description (match-string 2 text)))
                 (when (string-prefix-p "file" location)
                   ;; Remove link protocol.
                   (setq location (replace-regexp-in-string "^[a-zA-Z]+:" "" location))
                   ;; Skip property lines if including a whole file.
                   (let ((line-spec (if (string-match ".+::\\*+.+" location)
                                      (format ":lines \"%d-\"" (org-count-skip-lines-before-heading location)))))
                     (insert (format "#+include: \"%s\" %s :only-contents t" location line-spec)))
                   (write-file "shit.org"))))))))))
(add-hook 'org-export-before-processing-hook  #'org-export-to-latex-include-linked-headings)

This will have the effect that a linked heading with empty contents to a local file in any level will be exported using its actual content when exporting to latex/PDF.

Set org-export-to-latex-follow-heading-link to nil in buffers that you don't want this behavior!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.