Function: org-latex-headline
org-latex-headline is a byte-compiled function defined in
ox-latex.el.gz.
Signature
(org-latex-headline HEADLINE CONTENTS INFO)
Documentation
Transcode a HEADLINE element from Org to LaTeX.
CONTENTS holds the contents of the headline. INFO is a plist holding contextual information.
Source Code
;; Defined in /usr/src/emacs/lisp/org/ox-latex.el.gz
(defun org-latex-headline (headline contents info)
"Transcode a HEADLINE element from Org to LaTeX.
CONTENTS holds the contents of the headline. INFO is a plist
holding contextual information."
(unless (org-element-property :footnote-section-p headline)
(let* ((level (org-export-get-relative-level headline info))
;; "LaTeX TOC handling"
;; :unnumbered: toc will add the heading to the ToC
;; "Org TOC handling"
;; :unnumbered: notoc to suppress heading from the ToC
;; else include all headings (including unnumbered) like other modes
(unnumbered-type (org-export-get-node-property :UNNUMBERED headline t))
(numberedp (org-export-numbered-headline-p headline info))
;; Section formatting will set two placeholders: one for
;; the title and the other for the contents.
(section-fmt (org-latex--get-section-format headline info))
(text
(org-export-data-with-backend
(org-element-property :title headline)
org-latex--section-backend info))
(text-no-footnote
(org-export-data-with-backend
(org-element-property :title headline)
org-latex--section-no-footnote-backend info))
(todo
(and (plist-get info :with-todo-keywords)
(let ((todo (org-element-property :todo-keyword headline)))
(and todo (org-export-data todo info)))))
(todo-type (and todo (org-element-property :todo-type headline)))
(tags (and (plist-get info :with-tags)
(org-export-get-tags headline info)))
(priority (and (plist-get info :with-priority)
(org-element-property :priority headline)))
;; Create the headline text along with a no-tag version.
;; The latter is required to remove tags from toc.
(full-text (funcall (plist-get info :latex-format-headline-function)
todo todo-type priority text tags info))
(full-text-no-footnote
(funcall (plist-get info :latex-format-headline-function)
todo todo-type priority text-no-footnote tags info))
;; Associate \label to the headline for internal links.
(headline-label (org-latex--label headline info t t))
(pre-blanks
(make-string (org-element-property :pre-blank headline) ?\n)))
(if (or (not section-fmt) (org-export-low-level-p headline info))
;; This is a deep sub-tree: export it as a list item. Also
;; export as items headlines for which no section format has
;; been found.
(let ((low-level-body
(concat
;; If headline is the first sibling, start a list.
(when (org-export-first-sibling-p headline info)
(format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize)))
;; Itemize headline
"\\item"
(and full-text
(string-match-p "\\`[ \t]*\\[" full-text)
"\\relax")
" " full-text "\n"
headline-label
pre-blanks
contents)))
;; If headline is not the last sibling simply return
;; LOW-LEVEL-BODY. Otherwise, also close the list, before
;; any blank line.
(if (not (org-export-last-sibling-p headline info)) low-level-body
(replace-regexp-in-string
"[ \t\n]*\\'"
(format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
low-level-body)))
;; This is a standard headline. Export it as a section. Add
;; an alternative heading when possible, and when this is not
;; identical to the usual heading.
(let ((opt-title
(funcall (plist-get info :latex-format-headline-function)
todo todo-type priority
(org-export-data-with-backend
;; Returns alternative title when provided or
;; title itself.
(org-export-get-alt-title headline info)
org-latex--section-backend info)
(and (eq (plist-get info :with-tags) t) tags)
info))
;; Maybe end local TOC (see `org-latex-keyword').
(contents
(concat
contents
(let ((case-fold-search t)
(section
(let ((first (car (org-element-contents headline))))
(and (org-element-type-p first 'section) first))))
(org-element-map section 'keyword
(lambda (k)
(and (equal (org-element-property :key k) "TOC")
(let ((v (org-element-property :value k)))
(and (string-match-p "\\<headlines\\>" v)
(string-match-p "\\<local\\>" v)
(format "\\stopcontents[level-%d]" level)))))
info t)))))
;; When do we need to explicitly specify a heading for TOC?
;; 1. On numbered section with footnotes in title or alt_title
;; 2. On an unnumbered section if :UNNUMBERED: allows it regardless of footnotes
;; This applies to anything that may go into the ToC.
;; Specifically for paragraphs, see first answer of
;; https://tex.stackexchange.com/questions/288072/footnotes-within-paragraph
(let ((section-kw
(and (string-match "\\`\\\\\\(.+?\\){" section-fmt)
(match-string 1 section-fmt)))
need-alternative-toc-title)
(if (not section-kw)
;; We only know how to add \SECTION-KW{...} to TOC.
(setq need-alternative-toc-title nil)
(if (string-suffix-p "*" section-kw)
;; FIXME: In theory, user may customize section-fmt
;; to use, e.g. \section{...} for unnumbered headings
;; We do not handle such scenario.
(progn ;; unnumbered sections (ending with *)
;; Then we need to obey what the :UNNUMBERED: property says
(if org-latex-toc-include-unnumbered
;; Treat the ToC closer to what other exporters do
;; Include unnumbered section into TOC unless
;; explicitly requested not to.
(if (string= unnumbered-type "notoc")
(setq need-alternative-toc-title nil)
(setq need-alternative-toc-title t))
;; Ignore unnumbered headings in ToC - as in LaTeX
;; unless explicitly requested to include.
(if (string= unnumbered-type "toc")
(setq need-alternative-toc-title t)
(setq need-alternative-toc-title nil))))
;; Numbered sections
;; Specify special TOC title only when there is
;; opt-title or when title contains footnotes.
(if (and (string= full-text full-text-no-footnote) ;; no footnotes
;; opt-title is either ALT_TITLE or title itself
;; as returned by `org-export-get-alt-title'
(string= full-text opt-title)) ;; same alternative title
(setq need-alternative-toc-title nil)
(setq need-alternative-toc-title t))))
;; In all cases
;; Get rid of the footnotes in opt-title
(when (and (not (string= full-text-no-footnote full-text)) ;; when we have footnotess
(string= full-text opt-title)) ;; And we do not impose an alternative title
(setq opt-title full-text-no-footnote))
(if need-alternative-toc-title
(let ((new-format section-fmt)
(new-extra "")) ;; put the addcontentsline here
(if (string-suffix-p "*" section-kw)
;; Subsection that needs alternative title:
;; Keep section format, use \\addcontentsline
(setq new-extra
(format "\\addcontentsline{toc}{%s}{%s}\n"
(string-remove-suffix "*" section-kw)
opt-title))
;; section... we need the brackets
(let*
;; Replace square brackets with parenthesis
;; since square brackets are not supported in
;; optional arguments.
((un-bracketed-alt (replace-regexp-in-string
"\\[" "(" (replace-regexp-in-string "\\]" ")" opt-title)))
(replacement-re (concat
"\\1["
(replace-regexp-in-string (rx "\\") "\\\\" un-bracketed-alt nil t)
"]")))
(setq new-format (replace-match replacement-re nil nil section-fmt 1))))
(format new-format
full-text
(concat headline-label new-extra pre-blanks contents)))
;; Don't need or cannot have alternative heading.
;; Use regular sectioning format string.
(format section-fmt full-text
(concat headline-label pre-blanks contents)))))))))