From: Orm Finnendahl <orm.finnendahl@selma.hfmdk-frankfurt.de>
To: emacs-orgmode@gnu.org
Subject: Re: multipage html output
Date: Mon, 5 Aug 2024 18:52:02 +0200 [thread overview]
Message-ID: <ZrEDMt_gbf5oBTJB@orm-t14s> (raw)
In-Reply-To: <87bk2i8w07.fsf@localhost>
[-- Attachment #1: Type: text/plain, Size: 1730 bytes --]
Hi,
attached are the patches for the multipage html export proposal. The
tgz file contains all commits after branching from the main branch to
the org-html-multipage branch (see:
https://github.com/ormf/org-mode/tree/org-html-multipage)
There are also diffs for the only changed files, ox.el, ox-html.el and
org-manual.org between 2a4fdffac163e91f6ed2055ec34cbcadf8b95dec of the
main branch and my last commit to my org-html-multipage branch.
Let me know if there are problems or you need anything. I tried to be
conformant to Org in general and hope I succeeded. Let me know what
you think.
--
Orm
Am Samstag, den 27. Juli 2024 um 19:39:36 Uhr (+0000) schrieb Ihor Radchenko:
> Orm Finnendahl <orm.finnendahl@selma.hfmdk-frankfurt.de> writes:
>
> > html multipage output is fully working now in the org-export
> > compliant way sketched by Ihor.
>
> Great!
>
> > There is a small issue with org-export-as from ox.el: On my machine
> > applying the :filter-final-output functions to the final output
> > strings delete their :output-file Text Property. Below is a commented
> > somewhat ugly fix just to show what was necessary to make it
> > work. Maybe you have a better idea about how to change it.
>
> `org-html-final-function' strips the text properties. You can modify
> it. Or, better, you can add an additional filter to ox-html that will
> apply the necessary text properties (to make sure that user filters that
> do no care about text properties never interfere).
>
> --
> Ihor Radchenko // yantar92,
> Org mode contributor,
> Learn more about Org mode at <https://orgmode.org/>.
> Support Org development at <https://liberapay.com/org-mode>,
> or support my work at <https://liberapay.com/yantar92>
>
[-- Attachment #2: ox-html-multipage-patches.tgz --]
[-- Type: application/gzip, Size: 51795 bytes --]
[-- Attachment #3: ox.el.patch --]
[-- Type: text/plain, Size: 17371 bytes --]
*** org-mode/lisp/ox.el 2024-08-05 17:15:57.631928954 +0200
--- org-mode-multipage/lisp/ox.el 2024-08-03 12:57:24.346459632 +0200
***************
*** 215,220 ****
--- 215,221 ----
(:filter-latex-fragment . org-export-filter-latex-fragment-functions)
(:filter-line-break . org-export-filter-line-break-functions)
(:filter-link . org-export-filter-link-functions)
+ (:multipage-split . org-export-multipage-split-functions)
(:filter-node-property . org-export-filter-node-property-functions)
(:filter-options . org-export-filter-options-functions)
(:filter-paragraph . org-export-filter-paragraph-functions)
***************
*** 1883,1891 ****
INFO is a plist containing export directives."
(let ((type (org-element-type blob)))
;; Return contents only for complete parse trees.
! (if (eq type 'org-data) (lambda (_datum contents _info) contents)
! (let ((transcoder (cdr (assq type (plist-get info :translate-alist)))))
! (and (functionp transcoder) transcoder)))))
(defun org-export--keep-spaces (data info)
"Non-nil, when post-blank spaces after removing DATA should be preserved.
--- 1884,1894 ----
INFO is a plist containing export directives."
(let ((type (org-element-type blob)))
;; Return contents only for complete parse trees.
! (let ((transcoder (cdr (assq type (plist-get info :translate-alist)))))
! (cond
! ((functionp transcoder) transcoder)
! ;; Use default org-data transcoder unless specified.
! ((eq type 'org-data) #'org-export-transcode-org-data)))))
(defun org-export--keep-spaces (data info)
"Non-nil, when post-blank spaces after removing DATA should be preserved.
***************
*** 1928,1934 ****
The `:filter-parse-tree' filters are not applied.
! Return a string."
(or (gethash data (plist-get info :exported-data))
;; Handle broken links according to
;; `org-export-with-broken-links'.
--- 1931,1937 ----
The `:filter-parse-tree' filters are not applied.
! Return a string or a list of strings."
(or (gethash data (plist-get info :exported-data))
;; Handle broken links according to
;; `org-export-with-broken-links'.
***************
*** 2194,2199 ****
--- 2197,2205 ----
as a plist. It must return a string that will be used as the
final export output.")
+ (defvar org-export-multipage-split-functions nil
+ "List of functions applied when multipage output has to be split.")
+
;;;; Elements Filters
***************
*** 2537,2542 ****
--- 2543,2549 ----
(let (plist)
;; Install user-defined filters with `org-export-filters-alist'
;; and filters already in INFO (through ext-plist mechanism).
+ (setq tmp-info info)
(dolist (p org-export-filters-alist)
(let* ((prop (car p))
(info-value (plist-get info prop))
***************
*** 2548,2553 ****
--- 2555,2561 ----
(append (if (listp info-value) info-value
(list info-value))
default-value)))))
+ (setq global-prop org-export-filters-alist)
;; Prepend backend specific filters to that list.
(dolist (p (org-export-get-all-filters (plist-get info :back-end)))
;; Single values get consed, lists are appended.
***************
*** 2967,2973 ****
with external parameters overriding Org default settings, but
still inferior to file-local settings.
! Return code as a string."
(when (symbolp backend) (setq backend (org-export-get-backend backend)))
(org-export-barf-if-invalid-backend backend)
(org-fold-core-ignore-modifications
--- 2975,2983 ----
with external parameters overriding Org default settings, but
still inferior to file-local settings.
! Return code as a string or a list of strings.
! The returned strings will have their `org-export-info' property set to
! export information channel."
(when (symbolp backend) (setq backend (org-export-get-backend backend)))
(org-export-barf-if-invalid-backend backend)
(org-fold-core-ignore-modifications
***************
*** 3004,3034 ****
backend info subtreep visible-only ext-plist))
;; Eventually transcode TREE. Wrap the resulting string into
;; a template.
! (let* ((body (org-element-normalize-string
! (or (org-export-data (plist-get info :parse-tree) info)
! "")))
! (inner-template (cdr (assq 'inner-template
! (plist-get info :translate-alist))))
! (full-body (org-export-filter-apply-functions
! (plist-get info :filter-body)
! (if (not (functionp inner-template)) body
! (funcall inner-template body info))
! info))
! (template (cdr (assq 'template
! (plist-get info :translate-alist))))
! (output
! (if (or (not (functionp template)) body-only) full-body
! (funcall template full-body info))))
;; Call citation export finalizer.
(when (plist-get info :with-cite-processors)
! (setq output (org-cite-finalize-export output info)))
! ;; Remove all text properties since they cannot be
! ;; retrieved from an external process. Finally call
! ;; final-output filter and return result.
! (org-no-properties
! (org-export-filter-apply-functions
! (plist-get info :filter-final-output)
! output info)))))))))
(defun org-export--annotate-info (backend info &optional subtreep visible-only ext-plist)
"Annotate the INFO plist according to the BACKEND.
--- 3014,3059 ----
backend info subtreep visible-only ext-plist))
;; Eventually transcode TREE. Wrap the resulting string into
;; a template.
! (let ((output
! (or (org-export-data (plist-get info :parse-tree) info)
! "")))
! (setq output (ensure-list output))
;; Call citation export finalizer.
(when (plist-get info :with-cite-processors)
! (setq output
! (mapcar
! (lambda (o) (org-cite-finalize-export o info))
! output)))
! (let ((filters (plist-get info :filter-final-output)))
! ;; Call final-output filter and return result.
! (setq output
! (mapcar
! (lambda (o) (org-export-filter-apply-functions filters o info))
! output)))
! ;; Apply org-export-info property.
! (setq output
! (mapcar
! (lambda (o) (org-add-props o nil
! :output-file (get-text-property 0 :output-file o)
! 'org-export-info info))
! output))
! (if (length= output 1) (car output) output))))))))
!
! (defun org-export-transcode-org-data (_ body info)
! "Transcode `org-data' node with BODY. Return transcoded string.
! INFO is the communication channel plist."
! (let* ((inner-template (cdr (assq 'inner-template
! (plist-get info :translate-alist))))
! (full-body (org-export-filter-apply-functions
! (plist-get info :filter-body)
! (if (not (functionp inner-template)) body
! (funcall inner-template body info))
! info))
! (template (cdr (assq 'template
! (plist-get info :translate-alist))))
! (body-only (memq 'body-only (plist-get info :export-options))))
! (if (or (not (functionp template)) body-only) full-body
! (funcall template full-body info))))
(defun org-export--annotate-info (backend info &optional subtreep visible-only ext-plist)
"Annotate the INFO plist according to the BACKEND.
***************
*** 3107,3120 ****
(_ nil)))
;; Install user's and developer's filters.
(setq info (org-export-install-filters info))
;; Call options filters and update export options. We do not
;; use `org-export-filter-apply-functions' here since the
;; arity of such filters is different.
(let ((backend-name (org-export-backend-name backend)))
(dolist (filter (plist-get info :filter-options))
! (let ((result (funcall filter info backend-name)))
! (when result (setq info result)))))
;; Parse buffer.
(setq tree (org-element-parse-buffer nil visible-only 'defer))
;; Prune tree from non-exported elements and transform
;; uninterpreted elements or objects in both parse tree and
--- 3132,3147 ----
(_ nil)))
;; Install user's and developer's filters.
(setq info (org-export-install-filters info))
+
;; Call options filters and update export options. We do not
;; use `org-export-filter-apply-functions' here since the
;; arity of such filters is different.
(let ((backend-name (org-export-backend-name backend)))
(dolist (filter (plist-get info :filter-options))
! (let ((result (funcall filter info backend-name)))
! (when result (setq info result)))))
;; Parse buffer.
+
(setq tree (org-element-parse-buffer nil visible-only 'defer))
;; Prune tree from non-exported elements and transform
;; uninterpreted elements or objects in both parse tree and
***************
*** 3131,3136 ****
--- 3158,3166 ----
;; to communication channel. This is responsible for setting
;; :parse-tree to TREE.
(setq info (org-export--collect-tree-properties tree info))
+ (when (plist-get info :multipage)
+ (setq tree (org-export-filter-apply-functions
+ (plist-get info :multipage-split) tree info)))
;; Process citations and bibliography. Replace each citation
;; and "print_bibliography" keyword in the parse tree with
;; the output of the selected citation export processor.
***************
*** 6140,6145 ****
--- 6170,6195 ----
("uk" :html "Автор" :utf-8 "Автор")
("zh-CN" :html "作者" :utf-8 "作者")
("zh-TW" :html "作者" :utf-8 "作者"))
+ ("Chapter %s"
+ ("ar" :default "الفصل %s")
+ ("cs" :default "kapitola %s")
+ ("da" :default "kapitel %s")
+ ("de" :default "Kapitel %s")
+ ("es" :ascii "capitulo %s" :html "capítulo %s" :default "capítulo %s")
+ ("et" :html "peatükk %s" :utf-8 "peatükk %s")
+ ("fa" :default "فصل %s")
+ ("fr" :default "chapitre %s")
+ ("it" :default "capitolo %s")
+ ("ja" :default "章 %s")
+ ("nl" :default "hoofdstuk %s"
+ :html "hoofdstuk %s" :latex "hoofdstuk~%s")
+ ("pt_BR" :ascii "capitulo %s" :html "capítulo %s" :default "capítulo %s")
+ ("ro" :default "capitol %s")
+ ("ru" :html "глава %s"
+ :utf-8 "глава %s")
+ ("sl" :default "odsek %s")
+ ("tr" :html "bölüm" :default "bölüm %s")
+ ("zh-CN" :html "章节" :utf-8 "章节 %s"))
("Continued from previous page"
("ar" :default "تتمة الصفحة السابقة")
("cs" :default "Pokračování z předchozí strany")
***************
*** 6269,6274 ****
--- 6319,6326 ----
("sv" :default "Illustration")
("tr" :default "Şekil")
("zh-CN" :html "图" :utf-8 "图"))
+ ("Fig. %s"
+ ("de" :default "Abb. %s"))
("Figure %d:"
("ar" :default "شكل %d:")
("cs" :default "Obrázek %d:")
***************
*** 6436,6441 ****
--- 6488,6515 ----
("sl" :default "Reference")
("sv" :default "Referenser")
("tr" :default "Referanslar"))
+ ("Section %s"
+ ("ar" :default "انظر قسم %s")
+ ("cs" :default "sekce %s")
+ ("da" :default "afsnit %s")
+ ("de" :default "Abschnitt %s")
+ ("es" :ascii "seccion %s" :html "sección %s" :default "sección %s")
+ ("et" :html "peatükki %s" :utf-8 "peatükki %s")
+ ;; ("fa" :default "نمایش بخش %s")
+ ("fr" :default "section %s")
+ ("it" :default "sezione %s")
+ ;; ("ja" :default "セクション %s を参照")
+ ("nl" :default "sectie %s"
+ :html "sectie %s" :latex "sectie~%s")
+ ("pt_BR" :html "seção %s" :default "seção %s"
+ :ascii "secao %s")
+ ("ro" :default "secțiunea %s")
+ ("ru" :html "&раздел %s"
+ :utf-8 "раздел %s")
+ ("sl" :default "poglavje %d")
+ ("tr" :default "bölüm %s")
+ ;; ("zh-CN" :html "参见第%s节" :utf-8 "参见第%s节")
+ )
("See figure %s"
("cs" :default "Viz obrázek %s")
("et" :default "Vaata joonist %s")
***************
*** 6813,6818 ****
--- 6887,6918 ----
(switch-to-buffer-other-window buffer))
buffer)))
+ (defun org-export--write-output (output encoding)
+ "Write OUTPUT to file with ENCODING.
+ OUTPUT may be a string or a list of strings.
+ The target file is retrieved from :output-file OUTPUT property or
+ :output-file property in plist stored in `org-export-info' property of
+ each string.
+
+ Return the file name or a list of file names."
+ (if (listp output) (mapcar #'org-export--write-output output)
+ (setq tmp-debug output)
+ (let ((file (or
+ (get-text-property 0 :output-file output)
+ (plist-get
+ (get-text-property 0 'org-export-info output)
+ :output-file))))
+ (with-temp-buffer
+ (insert output)
+ ;; Ensure final newline. This is what was done
+ ;; historically, when we used `write-file'.
+ ;; Note that adding a newline is only safe for
+ ;; non-binary data.
+ (unless (bolp) (insert "\n"))
+ (let ((coding-system-for-write encoding))
+ (write-region nil nil file))
+ file))))
+
;;;###autoload
(defun org-export-to-file
(backend file &optional async subtreep visible-only body-only ext-plist
***************
*** 6861,6893 ****
`(let ((output
(org-export-as
',backend ,subtreep ,visible-only ,body-only
! ',ext-plist)))
! (with-temp-buffer
! (insert output)
! ;; Ensure final newline. This is what was done
! ;; historically, when we used `write-file'.
! ;; Note that adding a newline is only safe for
! ;; non-binary data.
! (unless (bolp) (insert "\n"))
! (let ((coding-system-for-write ',encoding))
! (write-region nil nil ,file)))
! (or (ignore-errors (funcall ',post-process ,file)) ,file)))
(let ((output (org-export-as
! backend subtreep visible-only body-only ext-plist)))
! (with-temp-buffer
! (insert output)
! ;; Ensure final newline. This is what was done
! ;; historically, when we used `write-file'.
! ;; Note that adding a newline is only safe for
! ;; non-binary data.
! (unless (bolp) (insert "\n"))
! (let ((coding-system-for-write encoding))
! (write-region nil nil file)))
(when (and (org-export--copy-to-kill-ring-p) (org-string-nw-p output))
(org-kill-new output))
;; Get proper return value.
! (or (and (functionp post-process) (funcall post-process file))
! file))))))
(defun org-export-output-file-name (extension &optional subtreep pub-dir)
"Return output file's name according to buffer specifications.
--- 6961,6983 ----
`(let ((output
(org-export-as
',backend ,subtreep ,visible-only ,body-only
! ',ext-plist))
! file)
! (setq file (org-export--write-output output ',encoding))
! (let ((post (lambda (f) (or (ignore-errors (funcall ',post-process f)) f))))
! (if (listp file) (mapcar post file) (funcall post file)))))
(let ((output (org-export-as
! backend subtreep visible-only body-only ext-plist))
! file)
! (setq file (org-export--write-output output encoding))
(when (and (org-export--copy-to-kill-ring-p) (org-string-nw-p output))
(org-kill-new output))
;; Get proper return value.
! (let ((post (lambda (f)
! (or (and (functionp post-process)
! (funcall post-process f))
! f))))
! (if (listp file) (mapcar post file) (funcall post file))))))))
(defun org-export-output-file-name (extension &optional subtreep pub-dir)
"Return output file's name according to buffer specifications.
[-- Attachment #4: ox-html.el.patch --]
[-- Type: text/plain, Size: 85342 bytes --]
*** org-mode/lisp/ox-html.el 2024-08-05 17:15:57.628595589 +0200
--- org-mode-multipage/lisp/ox-html.el 2024-08-05 17:11:54.979585435 +0200
***************
*** 4,9 ****
--- 4,11 ----
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
;; Jambunathan K <kjambunathan at gmail dot com>
+ ;; multipage export by Orm Finnendahl
+ ;; <orm dot finnendahl at selma dot hfmdk-frankfurt dot de>
;; Maintainer: TEC <orgmode@tec.tecosaur.net>
;; Keywords: outlines, hypermedia, calendar, text
***************
*** 82,88 ****
--- 84,94 ----
(latex-fragment . org-html-latex-fragment)
(line-break . org-html-line-break)
(link . org-html-link)
+ (multipage-inner-template . org-html-multipage-inner-template)
+ (multipage-template . org-html-multipage-template)
(node-property . org-html-node-property)
+ (org-data . org-html-transcode-org-data)
+ ;;; (org-page . org-html-transcode-org-page)
(paragraph . org-html-paragraph)
(plain-list . org-html-plain-list)
(plain-text . org-html-plain-text)
***************
*** 108,118 ****
--- 114,126 ----
(verse-block . org-html-verse-block))
:filters-alist '((:filter-options . org-html-infojs-install-script)
(:filter-parse-tree . org-html-image-link-filter)
+ (:multipage-split . org-html-multipage-split)
(:filter-final-output . org-html-final-function))
:menu-entry
'(?h "Export to HTML"
((?H "As HTML buffer" org-html-export-as-html)
(?h "As HTML file" org-html-export-to-html)
+ (?m "As HTML Multipage files" org-html-export-to-multipage)
(?o "As HTML file and open"
(lambda (a s v b)
(if a (org-html-export-to-html t s v b)
***************
*** 134,141 ****
(:html-head "HTML_HEAD" nil org-html-head newline)
(:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline)
(:subtitle "SUBTITLE" nil nil parse)
! (:html-head-include-default-style
! nil "html-style" org-html-head-include-default-style)
(:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts)
(:html-allow-name-attribute-in-anchors
nil nil org-html-allow-name-attribute-in-anchors)
--- 142,148 ----
(:html-head "HTML_HEAD" nil org-html-head newline)
(:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline)
(:subtitle "SUBTITLE" nil nil parse)
! (:html-head-include-default-style nil "html-style" org-html-head-include-default-style)
(:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts)
(:html-allow-name-attribute-in-anchors
nil nil org-html-allow-name-attribute-in-anchors)
***************
*** 158,163 ****
--- 165,190 ----
(:html-mathjax-options nil nil org-html-mathjax-options)
(:html-mathjax-template nil nil org-html-mathjax-template)
(:html-metadata-timestamp-format nil nil org-html-metadata-timestamp-format)
+ (:html-multipage-clear-export-directory nil "html-multipage-clear-export-directory"
+ org-html-multipage-clear-export-directory)
+ (:html-multipage-export-directory
+ nil "html-multipage-export-directory" org-html-multipage-export-directory)
+ (:html-multipage-head-include-default-style
+ nil "html-multipage-include-default-style" org-html-multipage-head-include-default-style)
+ (:html-multipage-join-empty-bodies
+ nil "html-multipage-join-empty-bodies" org-html-multipage-join-empty-bodies)
+ (:html-multipage-nav-format nil nil org-html-multipage-nav-format)
+ (:html-multipage-numbered-filenames nil "html-multipage-numbered-filenames"
+ org-html-multipage-numbered-filenames)
+ (:html-multipage-open nil "html-multipage-open" org-html-multipage-open)
+ (:html-multipage-postamble-position
+ nil "html-multipage-postamble-position" org-html-multipage-postamble-position)
+ (:html-multipage-preamble-position
+ nil "html-multipage-preamble-position" org-html-multipage-preamble-position)
+ (:html-multipage-split-hooks nil nil org-html-multipage-split-hooks)
+ (:html-multipage-split-level nil "html-multipage-split-level" org-html-multipage-split-level)
+ (:html-multipage-toc-to-top nil "html-multipage-toc-to-top" org-html-multipage-toc-to-top)
+ (:html-numbered-link-format nil nil org-html-numbered-link-format)
(:html-postamble-format nil nil org-html-postamble-format)
(:html-preamble-format nil nil org-html-preamble-format)
(:html-prefer-user-labels nil nil org-html-prefer-user-labels)
***************
*** 171,179 ****
nil nil org-html-table-use-header-tags-for-first-column)
(:html-tag-class-prefix nil nil org-html-tag-class-prefix)
(:html-text-markup-alist nil nil org-html-text-markup-alist)
(:html-todo-kwd-class-prefix nil nil org-html-todo-kwd-class-prefix)
(:html-toplevel-hlevel nil nil org-html-toplevel-hlevel)
! (:html-use-infojs nil nil org-html-use-infojs)
(:html-validation-link nil nil org-html-validation-link)
(:html-viewport nil nil org-html-viewport)
(:html-inline-images nil nil org-html-inline-images)
--- 198,207 ----
nil nil org-html-table-use-header-tags-for-first-column)
(:html-tag-class-prefix nil nil org-html-tag-class-prefix)
(:html-text-markup-alist nil nil org-html-text-markup-alist)
+ (:html-toc-title nil "html-toc-title" org-html-toc-title)
(:html-todo-kwd-class-prefix nil nil org-html-todo-kwd-class-prefix)
(:html-toplevel-hlevel nil nil org-html-toplevel-hlevel)
! (:html-use-infojs nil nil org-export-html-use-infojs)
(:html-validation-link nil nil org-html-validation-link)
(:html-viewport nil nil org-html-viewport)
(:html-inline-images nil nil org-html-inline-images)
***************
*** 186,191 ****
--- 214,221 ----
(:html-klipse-css nil nil org-html-klipse-css)
(:html-klipse-js nil nil org-html-klipse-js)
(:html-klipse-selection-script nil nil org-html-klipse-selection-script)
+ ;;; (:multipage-split nil nil org-html-multipage-split)
+ ;;; (:multipage nil nil org-html-multipage)
(:infojs-opt "INFOJS_OPT" nil nil)
;; Redefine regular options.
(:creator "CREATOR" nil org-html-creator-string)
***************
*** 462,467 ****
--- 492,720 ----
:package-version '(Org . "9.5")
:type 'string)
+ (defcustom org-html-multipage-style-default
+ "<style type=\"text/css\">
+ #content { margin: auto;
+ display: grid;
+ position: absolute;
+ padding-top: 1em;
+ grid-template-rows: 4em 1fr;
+ grid-template-columns: 27em 1fr;
+ grid-template-areas: \"toc title\"
+ \"toc content\";
+ }
+
+ header {
+ grid-area: title;
+ }
+
+ #table-of-contents {
+ grid-area: toc;
+ height: 100%;
+ }
+
+ #page-main-body {
+ grid-area: content;
+ height: 100%;
+ overflow: auto;
+ padding: 4em;
+ }
+
+ #page-text-body {
+ height: 100%;
+ width: 100%;
+ overflow: auto;
+ }
+
+ .title { text-align: center;
+ margin-bottom: .2em; }
+ .subtitle { text-align: center;
+ font-size: medium;
+ font-weight: bold;
+ margin-top:0; }
+ .todo { font-family: monospace; color: red; }
+ .done { font-family: monospace; color: green; }
+ .priority { font-family: monospace; color: orange; }
+ .tag { background-color: #eee; font-family: monospace;
+ padding: 2px; font-size: 80%; font-weight: normal; }
+ .timestamp { color: #bebebe; }
+ .timestamp-kwd { color: #5f9ea0; }
+ .org-right { margin-left: auto; margin-right: 0px; text-align: right; }
+ .org-left { margin-left: 0px; margin-right: auto; text-align: left; }
+ .org-center { margin-left: auto; margin-right: auto; text-align: center; }
+ .underline { text-decoration: underline; }
+ #postamble p, #preamble p { font-size: 90%; margin: .2em; }
+ p.verse { margin-left: 3%; }
+ pre {
+ border: 1px solid #e6e6e6;
+ border-radius: 3px;
+ background-color: #f2f2f2;
+ padding: 8pt;
+ font-family: monospace;
+ overflow: auto;
+ margin: 1.2em;
+ }
+ pre.src {
+ position: relative;
+ overflow: auto;
+ }
+ pre.src:before {
+ display: none;
+ position: absolute;
+ top: -8px;
+ right: 12px;
+ padding: 3px;
+ color: #555;
+ background-color: #f2f2f299;
+ }
+ pre.src:hover:before { display: inline; margin-top: 14px;}
+ /* Languages per Org manual */
+ pre.src-asymptote:before { content: 'Asymptote'; }
+ pre.src-awk:before { content: 'Awk'; }
+ pre.src-authinfo::before { content: 'Authinfo'; }
+ pre.src-C:before { content: 'C'; }
+ /* pre.src-C++ doesn't work in CSS */
+ pre.src-clojure:before { content: 'Clojure'; }
+ pre.src-css:before { content: 'CSS'; }
+ pre.src-D:before { content: 'D'; }
+ pre.src-ditaa:before { content: 'ditaa'; }
+ pre.src-dot:before { content: 'Graphviz'; }
+ pre.src-calc:before { content: 'Emacs Calc'; }
+ pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
+ pre.src-fortran:before { content: 'Fortran'; }
+ pre.src-gnuplot:before { content: 'gnuplot'; }
+ pre.src-haskell:before { content: 'Haskell'; }
+ pre.src-hledger:before { content: 'hledger'; }
+ pre.src-java:before { content: 'Java'; }
+ pre.src-js:before { content: 'Javascript'; }
+ pre.src-latex:before { content: 'LaTeX'; }
+ pre.src-ledger:before { content: 'Ledger'; }
+ pre.src-lisp:before { content: 'Lisp'; }
+ pre.src-lilypond:before { content: 'Lilypond'; }
+ pre.src-lua:before { content: 'Lua'; }
+ pre.src-matlab:before { content: 'MATLAB'; }
+ pre.src-mscgen:before { content: 'Mscgen'; }
+ pre.src-ocaml:before { content: 'Objective Caml'; }
+ pre.src-octave:before { content: 'Octave'; }
+ pre.src-org:before { content: 'Org mode'; }
+ pre.src-oz:before { content: 'OZ'; }
+ pre.src-plantuml:before { content: 'Plantuml'; }
+ pre.src-processing:before { content: 'Processing.js'; }
+ pre.src-python:before { content: 'Python'; }
+ pre.src-R:before { content: 'R'; }
+ pre.src-ruby:before { content: 'Ruby'; }
+ pre.src-sass:before { content: 'Sass'; }
+ pre.src-scheme:before { content: 'Scheme'; }
+ pre.src-screen:before { content: 'Gnu Screen'; }
+ pre.src-sed:before { content: 'Sed'; }
+ pre.src-sh:before { content: 'shell'; }
+ pre.src-sql:before { content: 'SQL'; }
+ pre.src-sqlite:before { content: 'SQLite'; }
+ /* additional languages in org.el's org-babel-load-languages alist */
+ pre.src-forth:before { content: 'Forth'; }
+ pre.src-io:before { content: 'IO'; }
+ pre.src-J:before { content: 'J'; }
+ pre.src-makefile:before { content: 'Makefile'; }
+ pre.src-maxima:before { content: 'Maxima'; }
+ pre.src-perl:before { content: 'Perl'; }
+ pre.src-picolisp:before { content: 'Pico Lisp'; }
+ pre.src-scala:before { content: 'Scala'; }
+ pre.src-shell:before { content: 'Shell Script'; }
+ pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
+ /* additional language identifiers per \"defun org-babel-execute\"
+ in ob-*.el */
+ pre.src-cpp:before { content: 'C++'; }
+ pre.src-abc:before { content: 'ABC'; }
+ pre.src-coq:before { content: 'Coq'; }
+ pre.src-groovy:before { content: 'Groovy'; }
+ /* additional language identifiers from org-babel-shell-names in
+ ob-shell.el: ob-shell is the only babel language using a lambda to put
+ the execution function name together. */
+ pre.src-bash:before { content: 'bash'; }
+ pre.src-csh:before { content: 'csh'; }
+ pre.src-ash:before { content: 'ash'; }
+ pre.src-dash:before { content: 'dash'; }
+ pre.src-ksh:before { content: 'ksh'; }
+ pre.src-mksh:before { content: 'mksh'; }
+ pre.src-posh:before { content: 'posh'; }
+ /* Additional Emacs modes also supported by the LaTeX listings package */
+ pre.src-ada:before { content: 'Ada'; }
+ pre.src-asm:before { content: 'Assembler'; }
+ pre.src-caml:before { content: 'Caml'; }
+ pre.src-delphi:before { content: 'Delphi'; }
+ pre.src-html:before { content: 'HTML'; }
+ pre.src-idl:before { content: 'IDL'; }
+ pre.src-mercury:before { content: 'Mercury'; }
+ pre.src-metapost:before { content: 'MetaPost'; }
+ pre.src-modula-2:before { content: 'Modula-2'; }
+ pre.src-pascal:before { content: 'Pascal'; }
+ pre.src-ps:before { content: 'PostScript'; }
+ pre.src-prolog:before { content: 'Prolog'; }
+ pre.src-simula:before { content: 'Simula'; }
+ pre.src-tcl:before { content: 'tcl'; }
+ pre.src-tex:before { content: 'TeX'; }
+ pre.src-plain-tex:before { content: 'Plain TeX'; }
+ pre.src-verilog:before { content: 'Verilog'; }
+ pre.src-vhdl:before { content: 'VHDL'; }
+ pre.src-xml:before { content: 'XML'; }
+ pre.src-nxml:before { content: 'XML'; }
+ /* add a generic configuration mode; LaTeX export needs an additional
+ (add-to-list 'org-latex-listings-langs '(conf \" \")) in .emacs */
+ pre.src-conf:before { content: 'Configuration File'; }
+
+ table { border-collapse:collapse; }
+ caption.t-above { caption-side: top; }
+ caption.t-bottom { caption-side: bottom; }
+ td, th { vertical-align:top; }
+ th.org-right { text-align: center; }
+ th.org-left { text-align: center; }
+ th.org-center { text-align: center; }
+ td.org-right { text-align: right; }
+ td.org-left { text-align: left; }
+ td.org-center { text-align: center; }
+ dt { font-weight: bold; }
+ .footpara { display: inline; }
+ .footdef { margin-bottom: 1em; }
+ .figure { padding: 1em; }
+ .figure p { text-align: center; }
+ .equation-container {
+ display: table;
+ text-align: center;
+ width: 100%;
+ }
+ .equation {
+ vertical-align: middle;
+ }
+ .equation-label {
+ display: table-cell;
+ text-align: right;
+ vertical-align: middle;
+ }
+ .inlinetask {
+ padding: 10px;
+ border: 2px solid gray;
+ margin: 10px;
+ background: #ffffcc;
+ }
+ #org-div-home-and-up
+ { text-align: right; font-size: 70%; white-space: nowrap; }
+ textarea { overflow-x: auto; }
+ .linenr { font-size: smaller }
+ .code-highlighted { background-color: #ffff00; }
+ .org-info-js_info-navigation { border-style: none; }
+ #org-info-js_console-label
+ { font-size: 10px; font-weight: bold; white-space: nowrap; }
+ .org-info-js_search-highlight
+ { background-color: #ffff00; color: #000000; font-weight: bold; }
+ .org-svg { }
+ </style>"
+ "The default style specification for exported HTML files.
+ You can use `org-html-head' and `org-html-head-extra' to add to
+ this style. If you don't want to include this default style,
+ customize `org-html-head-include-default-style'."
+ :group 'org-export-html
+ :package-version '(Org . "9.8")
+ :type 'string)
\f
;;; User Configuration Variables
***************
*** 486,492 ****
(home LINK_HOME :html-link-home))
"JavaScript options, long form for script, default values.")
! (defcustom org-html-use-infojs 'when-configured
"Non-nil when Sebastian Rose's Java Script org-info.js should be active.
This option can be nil or t to never or always use the script.
It can also be the symbol `when-configured', meaning that the
--- 739,745 ----
(home LINK_HOME :html-link-home))
"JavaScript options, long form for script, default values.")
! (defcustom org-export-html-use-infojs 'when-configured
"Non-nil when Sebastian Rose's Java Script org-info.js should be active.
This option can be nil or t to never or always use the script.
It can also be the symbol `when-configured', meaning that the
***************
*** 501,506 ****
--- 754,766 ----
(const :tag "When configured in buffer" when-configured)
(const :tag "Always" t)))
+ ;; (defcustom org-html-multipage nil
+ ;; "Boolean indicating multipage export."
+ ;; :group 'org-export-html
+ ;; :version "29.4"
+ ;; :package-version '(Org . "9.8")
+ ;; :type 'boolean)
+
(defcustom org-html-infojs-options
(mapcar (lambda (x) (cons (car x) (nth 2 x))) org-html-infojs-opts-table)
"Options settings for the INFOJS JavaScript.
***************
*** 849,854 ****
--- 1109,1129 ----
:group 'org-export-html
:type 'boolean)
+ (defcustom org-html-numbered-link-format
+ '("Chapter %s"
+ "Section %s"
+ "Fig. %s")
+ "Format for the labels of numbered links.
+
+ The first string is used for links to Chapters, the second for
+ links to Sections and the third for links to Figures. %s will be
+ replaced by the number of the reference. The strings get
+ translated using org-html--translate."
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'list)
+
;;;; Links :: Inline images
(defcustom org-html-inline-images t
***************
*** 1384,1389 ****
--- 1659,1673 ----
(list (string :tag "Language")
(string :tag "Format string"))))
+ (defcustom org-html-toc-title "Table of Contents"
+ "The string tp be used for the title of the table of contents. It
+ will be passed to org-html-translate."
+ :group 'org-export-html
+ :package-version '(Org . "9.8")
+ :version "29.4"
+ :type 'string
+ :safe #'stringp)
+
(defcustom org-html-validation-link
"<a href=\"https://validator.w3.org/check?uri=referer\">Validate</a>"
"Link to HTML validation service."
***************
*** 1522,1529 ****
--- 1806,1954 ----
:version "24.4"
:package-version '(Org . "8.0")
:type 'boolean)
+
+ (defcustom org-html-multipage-clear-export-directory t
+ "Boolean. If non-nil remove all .html files from the export
+ directory before exporting."
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'boolean)
+
+ (defcustom org-html-multipage-export-directory "html"
+ "The default directory for exported HTML files."
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'string)
+
+ (defcustom org-html-multipage-head-include-default-style t
+ "Non-nil means include the default style in exported HTML files.
+ The actual style is defined in `org-html-style-default' and
+ should not be modified. Use `org-html-head' to use your own
+ style information."
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'boolean)
+
+ (defcustom org-html-multipage-join-empty-bodies t
+ "Recursively join subheadlines, if a headline doesn't contain any
+ text before its Subheadline.
+
+ Example:
+
+ * Headline 1
+ ** Subheadline 1.1
+ *** Subsubheadline 1.1.1
+ Text of Subsubheadline 1.1.1
+
+ will be put on the same HTML page if this option is set,
+ otherwise Headline 1 And Subheadline 1.1 will be put on a
+ separate HTML page with empty content.
+ "
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'boolean)
+
+ (defcustom org-html-multipage-nav-format
+ '("<div id=\"org-div-nav-menu\">%s</div>"
+ "Next: <a accesskey=\"n\" href=\"%s\"> %s </a>, "
+ "Previous: <a accesskey=\"p\" href=\"%s\"> %s </a>, "
+ "Up: <a accesskey=\"u\" href=\"%s\"> %s </a>, "
+ "Home: <a accesskey=\"h\" href=\"%s\"> %s </a>")
+ "Snippets used to insert the NEXT, PREV, HOME and UP links in
+ multipage output. The list contains format strings for the HTML
+ div and the navigation elements. The %s in the HTML div will
+ receive a concatenated string of the navigation elements. The
+ first %s in the navigation elements will receive the link,
+ the second the title"
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'list)
+
+ (defcustom org-html-multipage-numbered-filenames t
+ "Boolean indicating whether filenames in multipage export should
+ get their headline-numbering prepended. Note: This option is
+ independent of the num: option and the backend guarantees that
+ filenames are unique in any case."
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'boolean)
+
+ (defcustom org-html-multipage-open 'nil
+ "If and where to open the top page of the multipage html after
+ export."
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type '(choice (const browser) (const buffer) (const nil)))
+
+ (defcustom org-html-multipage-postamble-position 'bottom
+ "The position of the postamble in the html output.
+
+ bottom - at the bottom of the page, directly before </body>
+
+ text-content - at the bottom of the text-content.
+ "
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type '(choice (const bottom) (const text-content)))
+
+ (defcustom org-html-multipage-preamble-position 'top
+ "If and where to open the top page of the multipage html after
+ export.
+
+ top - at the top of the page, directly after <body>
+
+ text-content - at the top of the text-content.
+
+ "
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type '(choice (const top) (const text-content)))
+
+ (defcustom org-html-multipage-split-hooks nil
+ "list of additional custom functions to be called during the
+ export after multipage splitting has taken place and before
+ transcoding with info as input.
+ "
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'list)
+
+ (defcustom org-html-multipage-split-level 'toc
+ "How to split the ORG file into multiple HTML pages.
+
+ toc - split each entry of the toc into a separate page.
+
+ number - a number indicating the maximum headline-level for
+ splitting.
+ "
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type '(choice (const toc) (number :tag "Headline Level" 3)))
+
+ (defcustom org-html-multipage-toc-to-top t
+ "If t links in the TOC will always point to the top of the page,
+ otherwise it will link directly to the referenced headline
+ element."
+ :group 'org-export-html
+ :version "29.4"
+ :package-version '(Org . "9.8")
+ :type 'boolean)
+
;;;###autoload
(put 'org-html-head-include-default-style 'safe-local-variable 'booleanp)
+ (put 'org-html-multipage-head-include-default-style 'safe-local-variable 'booleanp)
+ (put 'org-html-multipage-join-empty-bodies 'safe-local-variable 'booleanp)
(defcustom org-html-head ""
"Org-wide head definitions for exported HTML files.
***************
*** 1873,1890 ****
(defun org-html-footnote-section (info)
"Format the footnote section.
INFO is a plist used as a communication channel."
! (pcase (org-export-collect-footnote-definitions info)
(`nil nil)
(definitions
- (format
- (plist-get info :html-footnotes-section)
- (org-html--translate "Footnotes" info)
(format
! "\n%s\n"
! (mapconcat
! (lambda (definition)
! (pcase definition
! (`(,n ,label ,def)
;; Do not assign number labels as they appear in Org mode
;; - the footnotes are re-numbered by
;; `org-export-get-footnote-number'. If the label is not
--- 2298,2315 ----
(defun org-html-footnote-section (info)
"Format the footnote section.
INFO is a plist used as a communication channel."
! (pcase (org-export-collect-footnote-definitions info (plist-get info :tl-headline))
(`nil nil)
(definitions
(format
! (plist-get info :html-footnotes-section)
! (org-html--translate "Footnotes" info)
! (format
! "\n%s\n"
! (mapconcat
! (lambda (definition)
! (pcase definition
! (`(,n ,label ,def)
;; Do not assign number labels as they appear in Org mode
;; - the footnotes are re-numbered by
;; `org-export-get-footnote-number'. If the label is not
***************
*** 1911,1918 ****
(if (not inline?) contents
(format "<p class=\"footpara\">%s</p>"
contents))))))))
! definitions
! "\n"))))))
\f
;;; Template
--- 2336,2343 ----
(if (not inline?) contents
(format "<p class=\"footpara\">%s</p>"
contents))))))))
! definitions
! "\n"))))))
\f
;;; Template
***************
*** 2018,2025 ****
INFO is a plist used as a communication channel."
(org-element-normalize-string
(concat
! (when (plist-get info :html-head-include-default-style)
! (org-element-normalize-string org-html-style-default))
(org-html-normalize-string-or-function (plist-get info :html-head) info)
(org-html-normalize-string-or-function (plist-get info :html-head-extra)
info)
--- 2443,2453 ----
INFO is a plist used as a communication channel."
(org-element-normalize-string
(concat
! (if (plist-get info :multipage)
! (when (plist-get info :html-multipage-head-include-default-style)
! (org-element-normalize-string org-html-multipage-style-default))
! (when (plist-get info :html-head-include-default-style)
! (org-element-normalize-string org-html-style-default)))
(org-html-normalize-string-or-function (plist-get info :html-head) info)
(org-html-normalize-string-or-function (plist-get info :html-head-extra)
info)
***************
*** 2206,2212 ****
holding export options."
(concat
;; Table of contents.
! (let ((depth (plist-get info :with-toc)))
(when depth (org-html-toc depth info)))
;; Document contents.
contents
--- 2634,2644 ----
holding export options."
(concat
;; Table of contents.
! (let* ((with-toc (plist-get info :with-toc))
! (depth (if with-toc
! (if (numberp with-toc)
! with-toc
! (plist-get info :headline-levels)))))
(when depth (org-html-toc depth info)))
;; Document contents.
contents
***************
*** 2477,2484 ****
of contents as a string, or nil if it is empty."
(let ((toc-entries
(mapcar (lambda (headline)
! (cons (org-html--format-toc-headline headline info)
! (org-export-get-relative-level headline info)))
(org-export-collect-headlines info depth scope))))
(when toc-entries
(let* ((toc-id-counter (plist-get info :org-html--toc-counter))
--- 2909,2918 ----
of contents as a string, or nil if it is empty."
(let ((toc-entries
(mapcar (lambda (headline)
! (cl-list*
! (org-html--format-toc-headline headline info)
! nil ;;; no hidden attribute
! (org-export-get-relative-level headline info)))
(org-export-collect-headlines info depth scope))))
(when toc-entries
(let* ((toc-id-counter (plist-get info :org-html--toc-counter))
***************
*** 2497,2503 ****
(let ((top-level (plist-get info :html-toplevel-hlevel)))
(format "<h%d>%s</h%d>\n"
top-level
! (org-html--translate "Table of Contents" info)
top-level))
toc
(format "</%s>\n" outer-tag))))))))
--- 2931,2940 ----
(let ((top-level (plist-get info :html-toplevel-hlevel)))
(format "<h%d>%s</h%d>\n"
top-level
! (org-html--translate
! (or (plist-get info :html-toc-title)
! org-html-toc-title)
! info)
top-level))
toc
(format "</%s>\n" outer-tag))))))))
***************
*** 2505,2527 ****
(defun org-html--toc-text (toc-entries)
"Return innards of a table of contents, as a string.
TOC-ENTRIES is an alist where key is an entry title, as a string,
! and value is its relative level, as an integer."
! (let* ((prev-level (1- (cdar toc-entries)))
(start-level prev-level))
(concat
(mapconcat
(lambda (entry)
(let ((headline (car entry))
! (level (cdr entry)))
(concat
! (let* ((cnt (- level prev-level))
! (times (if (> cnt 0) (1- cnt) (- cnt))))
! (setq prev-level level)
! (concat
! (org-html--make-string
! times (cond ((> cnt 0) "\n<ul>\n<li>")
! ((< cnt 0) "</li>\n</ul>\n")))
! (if (> cnt 0) "\n<ul>\n<li>" "</li>\n<li>")))
headline)))
toc-entries "")
(org-html--make-string (- prev-level start-level) "</li>\n</ul>\n"))))
--- 2942,2974 ----
(defun org-html--toc-text (toc-entries)
"Return innards of a table of contents, as a string.
TOC-ENTRIES is an alist where key is an entry title, as a string,
! second element a flag whether the entry gets a
! class=\"toc-hidden\" attribute and the third element is its
! relative level, as an integer."
! (let* ((prev-level (1- (cddar toc-entries)))
(start-level prev-level))
(concat
(mapconcat
(lambda (entry)
(let ((headline (car entry))
! (hidden (cadr entry))
! (level (cddr entry)))
(concat
! (format
! (let* ((cnt (- level prev-level))
! (times (if (> cnt 0) (1- cnt) (- cnt))))
! (setq prev-level level)
! (concat
! (org-html--make-string
! times (cond ((> cnt 0) (format "\n<ul class=\"ul-toc-level-%d\">\n<li>" level))
! ((< cnt 0) "</li>\n</ul>\n")))
! (if (> cnt 0)
! (concat "\n<ul"
! (format " class=\"ul-toc-level-%d\"" level)
! ">\n<li%s>")
! "</li>\n<li%s>")))
! (if hidden (format " class=\"toc-hidden toc-level-%d\"" level)
! (format " class=\"toc-level-%d\"" level)))
headline)))
toc-entries "")
(org-html--make-string (- prev-level start-level) "</li>\n</ul>\n"))))
***************
*** 2572,2578 ****
(org-html--translate "Listing %d:" info))))
(mapconcat
(lambda (entry)
! (let ((label (org-html--reference entry info t))
(title (org-trim
(org-export-data
(or (org-export-get-caption entry t)
--- 3019,3025 ----
(org-html--translate "Listing %d:" info))))
(mapconcat
(lambda (entry)
! (let ((label (org-html--full-reference entry info t))
(title (org-trim
(org-export-data
(or (org-export-get-caption entry t)
***************
*** 2610,2616 ****
(org-html--translate "Table %d:" info))))
(mapconcat
(lambda (entry)
! (let ((label (org-html--reference entry info t))
(title (org-trim
(org-export-data
(or (org-export-get-caption entry t)
--- 3057,3063 ----
(org-html--translate "Table %d:" info))))
(mapconcat
(lambda (entry)
! (let ((label (org-html--full-reference entry info t))
(title (org-trim
(org-export-data
(or (org-export-get-caption entry t)
***************
*** 2759,2765 ****
(let ((prev (org-export-get-previous-element footnote-reference info)))
(when (org-element-type-p prev 'footnote-reference)
(plist-get info :html-footnote-separator)))
! (let* ((n (org-export-get-footnote-number footnote-reference info))
(label (org-element-property :label footnote-reference))
;; Do not assign number labels as they appear in Org mode -
;; the footnotes are re-numbered by
--- 3206,3215 ----
(let ((prev (org-export-get-previous-element footnote-reference info)))
(when (org-element-type-p prev 'footnote-reference)
(plist-get info :html-footnote-separator)))
! (let* ((n (org-export-get-footnote-number
! footnote-reference info
! (if (plist-get info :multipage)
! (org-html-get-multipage-tl-headline footnote-reference info))))
(label (org-element-property :label footnote-reference))
;; Do not assign number labels as they appear in Org mode -
;; the footnotes are re-numbered by
***************
*** 2795,2801 ****
CONTENTS holds the contents of the headline. INFO is a plist
holding contextual information."
(unless (org-element-property :footnote-section-p headline)
! (let* ((numberedp (org-export-numbered-headline-p headline info))
(numbers (org-export-get-headline-number headline info))
(level (+ (org-export-get-relative-level headline info)
(1- (plist-get info :html-toplevel-hlevel))))
--- 3245,3253 ----
CONTENTS holds the contents of the headline. INFO is a plist
holding contextual information."
(unless (org-element-property :footnote-section-p headline)
! (let* ((numberedp (if (plist-get info :multipage)
! (plist-get info :section-numbers)
! (org-export-numbered-headline-p headline info)))
(numbers (org-export-get-headline-number headline info))
(level (+ (org-export-get-relative-level headline info)
(1- (plist-get info :html-toplevel-hlevel))))
***************
*** 3023,3028 ****
--- 3475,3481 ----
((string= key "HTML") value)
((string= key "TOC")
(let ((case-fold-search t))
+ (setq global-key keyword)
(cond
((string-match "\\<headlines\\>" value)
(let ((depth (and (string-match "\\<[0-9]+\\>" value)
***************
*** 3033,3039 ****
(org-export-resolve-link
(org-strip-quotes (match-string 1 value)) info))
((string-match-p "\\<local\\>" value) keyword)))) ;local
! (org-html-toc depth info scope)))
((string= "listings" value) (org-html-list-of-listings info))
((string= "tables" value) (org-html-list-of-tables info))))))))
--- 3486,3496 ----
(org-export-resolve-link
(org-strip-quotes (match-string 1 value)) info))
((string-match-p "\\<local\\>" value) keyword)))) ;local
! (if (plist-get info :multipage)
! (progn
! (setq global-key keyword)
! (org-html-multipage-toc depth (cl-list* :full-toc t info) scope))
! (org-html-toc depth info scope))))
((string= "listings" value) (org-html-list-of-listings info))
((string= "tables" value) (org-html-list-of-tables info))))))))
***************
*** 3187,3193 ****
(defun org-html-image-link-filter (data _backend info)
"Process image links that are inside descriptions.
! DATA is the parse tree. INFO is and info plist.
See `org-export-insert-image-links' for more details."
(org-export-insert-image-links data info org-html-inline-image-rules))
--- 3644,3650 ----
(defun org-html-image-link-filter (data _backend info)
"Process image links that are inside descriptions.
! DATA is the parse tree. INFO is an info plist.
See `org-export-insert-image-links' for more details."
(org-export-insert-image-links data info org-html-inline-image-rules))
***************
*** 3367,3389 ****
(org-element-property :raw-link link) info))))
;; Link points to a headline.
(`headline
! (let ((href (org-html--reference destination info))
;; What description to use?
(desc
;; Case 1: Headline is numbered and LINK has no
;; description. Display section number.
(if (and (org-export-numbered-headline-p destination info)
(not desc))
! (mapconcat #'number-to-string
! (org-export-get-headline-number
! destination info) ".")
;; Case 2: Either the headline is un-numbered or
;; LINK has a custom description. Display LINK's
;; description or headline's title.
(or desc
(org-export-data
(org-element-property :title destination) info)))))
! (format "<a href=\"#%s\"%s>%s</a>" href attributes desc)))
;; Fuzzy link points to a target or an element.
(_
(if (and destination
--- 3824,3860 ----
(org-element-property :raw-link link) info))))
;; Link points to a headline.
(`headline
! (let ((href
! (org-html--full-reference
! (if (plist-get info :multipage)
! (alist-get destination
! (plist-get info :stripped-hl-to-parse-tree-hl))
! destination)
! info))
;; What description to use?
(desc
;; Case 1: Headline is numbered and LINK has no
;; description. Display section number.
(if (and (org-export-numbered-headline-p destination info)
(not desc))
! (let ((headline-number (org-export-get-headline-number
! destination info)))
! (if (> (length headline-number) 1)
! (format
! (org-html--translate (nth 1 org-html-numbered-link-format) info)
! (mapconcat #'number-to-string
! headline-number "."))
! (format
! (org-html--translate (nth 0 org-html-numbered-link-format) info)
! (mapconcat #'number-to-string
! headline-number "."))))
;; Case 2: Either the headline is un-numbered or
;; LINK has a custom description. Display LINK's
;; description or headline's title.
(or desc
(org-export-data
(org-element-property :title destination) info)))))
! (format "<a href=\"%s\"%s>%s</a>" href attributes desc)))
;; Fuzzy link points to a target or an element.
(_
(if (and destination
***************
*** 3394,3422 ****
;; environment. Use "ref" or "eqref" macro, depending on user
;; preference to refer to those in the document.
(format (plist-get info :html-equation-reference-format)
! (org-html--reference destination info))
! (let* ((ref (org-html--reference destination info))
(org-html-standalone-image-predicate
#'org-html--has-caption-p)
(counter-predicate
(if (org-element-type-p destination 'latex-environment)
#'org-html--math-environment-p
#'org-html--has-caption-p))
! (number
(cond
(desc nil)
((org-html-standalone-image-p destination info)
! (org-export-get-ordinal
! (org-element-map destination 'link #'identity info t)
! info '(link) 'org-html-standalone-image-p))
(t (org-export-get-ordinal
destination info nil counter-predicate))))
(desc
(cond (desc)
! ((not number) "No description for this link")
! ((numberp number) (number-to-string number))
(t (mapconcat #'number-to-string number ".")))))
! (format "<a href=\"#%s\"%s>%s</a>" ref attributes desc)))))))
;; Coderef: replace link with the reference name or the
;; equivalent line number.
((string= type "coderef")
--- 3865,3895 ----
;; environment. Use "ref" or "eqref" macro, depending on user
;; preference to refer to those in the document.
(format (plist-get info :html-equation-reference-format)
! (org-html--full-reference destination info))
! (let* ((ref (org-html--full-reference destination info))
(org-html-standalone-image-predicate
#'org-html--has-caption-p)
(counter-predicate
(if (org-element-type-p destination 'latex-environment)
#'org-html--math-environment-p
#'org-html--has-caption-p))
! (numbered-ref
(cond
(desc nil)
((org-html-standalone-image-p destination info)
! (format (org-html--translate (nth 2 org-html-numbered-link-format) info)
! (org-export-get-ordinal
! (org-element-map destination 'link #'identity info t)
! info '(link) 'org-html-standalone-image-p)))
(t (org-export-get-ordinal
destination info nil counter-predicate))))
(desc
(cond (desc)
! ((not numbered-ref) "No description for this link")
! ((numberp numbered-ref) (number-to-string number))
! ((stringp numbered-ref) numbered-ref)
(t (mapconcat #'number-to-string number ".")))))
! (format "<a href=\"%s\"%s>%s</a>" ref attributes desc)))))))
;; Coderef: replace link with the reference name or the
;; equivalent line number.
((string= type "coderef")
***************
*** 3924,3930 ****
"Transcode a TARGET object from Org to HTML.
CONTENTS is nil. INFO is a plist holding contextual
information."
! (let ((ref (org-html--reference target info)))
(org-html--anchor ref nil nil info)))
;;;; Timestamp
--- 4397,4403 ----
"Transcode a TARGET object from Org to HTML.
CONTENTS is nil. INFO is a plist holding contextual
information."
! (let ((ref (org-html--full-reference target info)))
(org-html--anchor ref nil nil info)))
;;;; Timestamp
***************
*** 3984,3990 ****
(delay-mode-hooks (set-auto-mode t))
(when (plist-get info :html-indent)
(indent-region (point-min) (point-max)))
! (buffer-substring-no-properties (point-min) (point-max))))
\f
;;; End-user functions
--- 4457,4470 ----
(delay-mode-hooks (set-auto-mode t))
(when (plist-get info :html-indent)
(indent-region (point-min) (point-max)))
! (if (plist-get info :multipage)
! (let ((output-file (get-text-property
! 0 :output-file
! (buffer-substring (point-min) (point-max)))))
! (put-text-property
! 0 1 :output-file output-file
! (buffer-substring-no-properties (point-min) (point-max))))
! (buffer-substring-no-properties (point-min) (point-max)))))
\f
;;; End-user functions
***************
*** 4092,4097 ****
--- 4572,5482 ----
"html"))
plist pub-dir))
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;;;
+ ;;; Code specific to the multipage backend
+ ;;;
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ (defun org-html-reverse-assoc-list (assoc-list)
+ (mapcar (lambda (entry) (cons (cdr entry) (car entry))) assoc-list))
+
+ (defun org-html-element-title (element)
+ (org-element-property :raw-value element))
+
+ (defun org-html-increment-string-idx (string)
+ (if (string-match "\\([0-9]+\\)$" string)
+ (replace-match (format "%s" (1+ (read (match-string 0 string)))) nil nil string)
+ (format "%s-1" string)))
+
+ (defun org-html-unique-filename (string filenames)
+ "return a unique filename by appending -<num> to the string with
+ <num> starting from 1 and incrementing until the string is
+ unique in filenames."
+ (if (member string filenames)
+ (org-html-unique-filename
+ (org-html-increment-string-idx string) filenames)
+ string))
+
+ (defun org-html-replace-chars-with-dash (chars string)
+ (cl-reduce (lambda (accum x) (replace-regexp-in-string (format "%s+" x) "-" accum))
+ chars
+ :initial-value string))
+
+ (defun org-html-remove-chars (chars string)
+ (cl-reduce (lambda (accum x) (replace-regexp-in-string (format "%s+" x) "" accum))
+ chars
+ :initial-value string))
+
+ (defun org-html-string-to-filename (string)
+ (replace-regexp-in-string
+ "-+" "-"
+ (org-html-remove-chars
+ '("(" ")" "*" "," ";" "{" "}" "'" "\\" "?")
+ (org-html-replace-chars-with-dash
+ '(" " "_" ":" "/")
+ (replace-regexp-in-string
+ "\\\\ast{}" "*"
+ (downcase (string-trim string)))))))
+
+ (defun org-html-string-prepend-section-numbering (string levels maxlevel)
+ "Prepend the chapter outline numbers given in levels to
+ string. Truncate levels to maxlevel or pad with zeroes if
+ required."
+ (cl-loop
+ for i from (1- maxlevel) downto 0
+ with result = string
+ do (setq result (format "%02d_%s" (or (nth i levels) 0) result))
+ finally (return result)))
+
+ (defun org-html--get-multipage-page-url (element info)
+ "Return the url of the page containing ELEMENT."
+ (alist-get
+ (org-html-get-multipage-tl-headline element info)
+ (plist-get info :tl-url-lookup)))
+
+ (defun org-html--full-reference (destination info &optional page-only)
+ "Return an appropriate reference for DESTINATION. Like
+ org-html--reference, but generating an extended cross-page
+ reference for multipage.
+
+ DESTINATION is an element or a `target' type object. INFO is the
+ current export state, as a plist.
+
+ When PAGE-ONLY is non-nil just return the page reference."
+ (if (plist-get info :multipage)
+ (concat (org-html--get-multipage-page-url destination info)
+ (if page-only ""
+ (format "#%s" (org-export-get-reference destination info))))
+ (format "#%s" (org-export-get-reference destination info))))
+
+ (defun org-html-multipage-toc (depth info &optional scope)
+ "Build a table of contents for a page in multipage
+ export. `:tl-headline-number' and `:tl-headline' refer to the
+ current page and have to be supplied in INFO.
+
+ DEPTH is an integer specifying the depth of the table. INFO is a
+ plist used as a communication channel. Optional argument SCOPE
+ is an element defining the scope of the table. Return the table
+ of contents as a string, or nil if it is empty."
+ (let* ((tl-headline-number (plist-get info :tl-headline-number))
+ (tl-headline (unless (plist-get info :full-toc) (plist-get info :tl-headline)))
+ (curr-number-ref tl-headline-number)
+ (toc-entries
+ (cl-loop
+ for (entry . props) in (plist-get info :multipage-toc-lookup)
+ if (<= (length (plist-get props :toc-hl-number)) depth)
+ collect (let* ((tl-hl (plist-get props :tl-hl))
+ (page-headline-number (plist-get props :page-hl-number)))
+ (if (eq tl-hl tl-headline)
+ (setf curr-number-ref page-headline-number))
+ (cl-list*
+ (org-html--format-mp-toc-headline
+ (plist-get props :href)
+ (plist-get props :toc-body)
+ (equal (plist-get props :tl-hl) tl-headline)
+ (plist-get info :full-toc))
+ (unless (plist-get info :full-toc)
+ (org-html--hidden-in-toc? page-headline-number
+ curr-number-ref))
+ (plist-get props :relative-level))))))
+ (when toc-entries
+ (let ((toc (concat "<div id=\"text-table-of-contents\" role=\"doc-toc\">"
+ (org-html--toc-text toc-entries)
+ "</div>\n")))
+ (if scope toc
+ (let ((outer-tag (if (org-html--html5-fancy-p info)
+ "nav"
+ "div")))
+ (concat (format "<%s id=\"table-of-contents\" role=\"doc-toc\">\n" outer-tag)
+ (let ((top-level (plist-get info :html-toplevel-hlevel)))
+ (format "<h%d>%s</h%d>\n"
+ top-level
+ (org-html--translate
+ (or (plist-get info :html-toc-title)
+ org-html-toc-title)
+ info)
+ top-level))
+ toc
+ (format "</%s>\n" outer-tag))))))))
+
+ (defun org-html--get-toc-body (headline info)
+ "Return the body of the toc entry of HEADLINE. INFO is a plist
+ used as a communication channel."
+ (let* ((headline-number (org-html-get-multipage-headline-number headline 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)))
+ (priority (and (plist-get info :with-priority)
+ (org-element-property :priority headline)))
+ (text (org-export-data-with-backend
+ (org-export-get-alt-title headline info)
+ (org-export-toc-entry-backend 'html)
+ info))
+ (tags (and (eq (plist-get info :with-tags) t)
+ (org-export-get-tags headline info))))
+ ;; Body.
+ (concat
+ (and (not (org-export-low-level-p headline info))
+ (plist-get info :section-numbers)
+ (concat
+ (mapconcat #'number-to-string headline-number ".")
+ " "))
+ (apply (plist-get info :html-format-headline-function)
+ todo todo-type priority text tags :section-number nil))))
+
+ (defun org-html--format-mp-toc-headline (href body active full-toc)
+ "Return a table of contents entry for multipage output."
+ (format "<a %s>%s</a>"
+ ;; Target
+ (format "href=\"%s\"%s"
+ href
+ (concat
+ "class=\""
+ (if full-toc "inline-toc-entry"
+ "toc-entry")
+ (if active
+ " toc-active" "")
+ "\""))
+
+ ;; Body.
+ body))
+
+ (defun org-html-multipage-ensure-export-dir (dir)
+ "get the full pathname of dir and ensure it exists."
+ (when (symbolp dir) (setq dir (format "%s" dir)))
+ (unless (= (aref dir 0) 47)
+ (setq dir (concat (file-name-directory (buffer-file-name)) dir)))
+ (unless (file-directory-p dir)
+ (make-directory dir :parents))
+ dir)
+
+ (defun org-html-multipage-split-tree (info)
+ (let ((split-ref (plist-get info :html-multipage-split-level))
+ (headline-numbering (plist-get info :headline-numbering)))
+ (cond
+ ((eq split-ref 'toc)
+ (let ((maxdepth (if (numberp (plist-get info :with-toc))
+ (plist-get info :with-toc)
+ (plist-get info :headline-levels))))
+ (plist-put info :export-depth maxdepth)
+ (org-html-page-headlines
+ (cl-remove-if (lambda (hl-num) (> (length hl-num) maxdepth))
+ headline-numbering :key 'cdr)
+ info)))
+ ((numberp split-ref)
+ (plist-put info :export-depth split-ref)
+ (org-html-page-headlines
+ (cl-remove-if (lambda (hl-num) (> (length hl-num) split-ref))
+ headline-numbering :key 'cdr)
+ info)))))
+
+ (defun org-html-transcode-multipage (info &optional body-only)
+ "Central routine transcoding to multipage output called by
+ `org-html-transcode-org-data' called from `org-export-as'.
+
+ The pages to be exported are in the :multipage-org-pages property
+ of info as a list of org-page pseudo elements. This function
+ transcodes the org-pages and returns a list of the transcoded
+ output strings with their filename as :output-file Text Property
+ to be further processed by the function calling `org-export-as'.
+
+ INFO is the communication channel.
+ "
+ (let ((async (plist-get info :async))
+ (post-process (plist-get info :post-process)))
+ (declare (indent 2))
+ (setq global-output
+ (cl-loop
+ for org-page in (plist-get info :multipage-org-pages)
+ collect (let ((file (org-element-property :output-file org-page)))
+ (message "transcoding: %s" file)
+ (let ((output (org-html-transcode-org-page org-page info)))
+ (put-text-property 0 1 :output-file file output)
+ output))))))
+
+ (defun org-html-multipage-split (data _backend info)
+ "Filter routine to collect all properties relevant to multipage
+ output. It is called in the context of calling all
+ :filter-parse-tree alist functions in `org-export-annotate-info'
+ after the parse-tree is completed and its properties
+ collected. The function takes care of splitting the parse-tree
+ into the subtrees for each page, creating org-page pseudo
+ elements, adding them in a list in the :multipage-org-pages
+ property of info. In addition lookup alists for the stripped
+ pages, for the page-urls, the navigation elements, the toc,
+ etc. are added to info, which are needed by the html transcoders.
+
+ DATA is the completed parse-tree of the document.
+
+ INFO is the communication channel.
+ "
+ (if (plist-get info :multipage)
+ (let ((dir (plist-get info :verified-export-directory))
+ (async (plist-get info :async))
+ (post-process (plist-get info :post-process)))
+ (declare (indent 2))
+ (plist-put info :headline-numbering
+ (org-export--collect-headline-numbering
+ (plist-get info :parse-tree)
+ (cl-list* :section-numbers t info)))
+ (if (not (file-writable-p dir)) (error "Output dir not writable")
+ (let* ((encoding (or org-export-coding-system buffer-file-coding-system))
+ (headline-numbering (plist-get info :headline-numbering))
+ ;; each entry in exported-headline-numbering will become a
+ ;; single page in multipage output.
+ (exported-headline-numbering
+ (let ((tmp (org-html-multipage-split-tree info)))
+ (plist-put info :exported-headline-numbering tmp)
+ tmp))
+ (max-toc-depth (if (numberp (plist-get info :with-toc))
+ (plist-get info :with-toc)
+ (plist-get info :headline-levels)))
+ ;; section-trees is a list of all sections which get
+ ;; exported to a single page
+ (section-trees
+ (cl-loop
+ for section-entry in exported-headline-numbering
+ for keep-first-subhls = (plist-get info :keep-first-subhls) then (cdr keep-first-subhls)
+ collect
+ (let* ((section-number (cdr section-entry)))
+ (if (< (length section-number) max-toc-depth)
+ (org-html-element-remove-subheadlines
+ (car section-entry)
+ (car keep-first-subhls)
+ max-toc-depth)
+ (org-html-element-copy-element (car section-entry))))))
+ ;; stripped-section-headline-numbering is the equivalent of
+ ;; headline-numbering but replacing the car of its elements
+ ;; with the stripped version of the headlines.
+ (stripped-section-headline-numbering
+ (cl-mapcar 'cons
+ (cl-loop for section in section-trees
+ ;; collect all subheadlines to match
+ ;; headline-numbering:
+ append (org-element-map section 'headline
+ 'identity))
+ (mapcar 'cdr headline-numbering)))
+ ;; lookup from all toc headline-numbers to the tl-headline.
+ )
+ ;; add stripped-section-headline-numbering to
+ ;; :headline-numbering, to make their headline-numbering
+ ;; accessible when generating the body of the individual
+ ;; pages.
+ (plist-put info :headline-numbering
+ (append
+ headline-numbering
+ stripped-section-headline-numbering))
+ (plist-put info :section-trees section-trees)
+ (plist-put info :stripped-section-headline-numbering
+ stripped-section-headline-numbering)
+ ;; tl-url-lookup associates the stripped section headlines
+ ;; with the names of the joined pages to export.
+ (plist-put info :tl-url-lookup (org-html--generate-tl-url-lookup info))
+ ;; lookup for the navigation elements of each page.
+ (plist-put info :section-nav-lookup
+ (org-html--make-section-nav-lookup info))
+ (let ((section-filenames
+ (mapcar
+ (lambda (hl) (alist-get hl (plist-get info :tl-url-lookup)))
+ section-trees)))
+ (plist-put info :section-filenames section-filenames)
+ ;; bidirectional lookup tables to map between the
+ ;; stripped-section headlines and their global
+ ;; parse-tree equvialent.
+ (plist-put
+ info :stripped-hl-to-parse-tree-hl
+ (append
+ (cl-mapcar 'cons
+ (mapcar 'car stripped-section-headline-numbering)
+ (mapcar 'car headline-numbering))
+ (cl-mapcar 'cons
+ (mapcar 'car headline-numbering)
+ (mapcar 'car stripped-section-headline-numbering))))
+ ;; collect the toc information to avoid repeated
+ ;; recalculation in the toc transcoder for the
+ ;; individual pages.
+ (plist-put info :multipage-toc-lookup
+ (org-html--make-multipage-toc-lookup info))
+ ;; The url for the "top" link on each page.
+ (plist-put info :html-top-url
+ (alist-get
+ (car (plist-get info :section-trees))
+ (plist-get info :tl-url-lookup)))
+ ;; The title for the "top" link on each page.
+ (plist-put info :html-top-title
+ (org-html-element-title
+ (car (plist-get info :section-trees))))
+ ;; collect all org-pages to be exported.
+ (plist-put info :multipage-org-pages
+ (cl-loop
+ for file in section-filenames
+ for tl-headline in section-trees
+ collect
+ (list 'org-page
+ (list :output-file (format "%s/%s" dir file)
+ :tl-headline tl-headline
+ :tl-headline-number
+ (alist-get
+ tl-headline
+ stripped-section-headline-numbering))
+ nil))))))))
+ data)
+
+ (defun org-html--generate-tl-url-lookup (info)
+ "Return an assoc list for all headlines appearing in the toc
+ and the url names of the page they're on."
+ (let ((extension (plist-get info :html-extension))
+ (stripped-section-headline-numbering
+ (plist-get info :stripped-section-headline-numbering))
+ filenames)
+ (mapcar
+ (lambda (entry)
+ (let* ((tl-elem (org-html-element-get-top-level entry))
+ (title (org-html-element-title tl-elem)))
+ (cons
+ entry
+ (format "%s.%s"
+ (car (push
+ (org-html-unique-filename
+ (if (plist-get info :html-multipage-numbered-filenames)
+ (org-html-string-prepend-section-numbering
+ (org-html-string-to-filename title)
+ (cdr (assoc
+ tl-elem
+ stripped-section-headline-numbering))
+ org-export-headline-levels)
+ (org-html-string-to-filename title))
+ filenames)
+ filenames))
+ extension))))
+ (plist-get info :section-trees))))
+
+ (defun org-html--make-section-nav-lookup (info)
+ "Return an assoc-list for the headlines of all
+ exported pages with a plist containing titles and urls for the
+ section and its navigation."
+ (let* ((stripped-section-headline-numbering (plist-get info :stripped-section-headline-numbering))
+ ;;; first collect navigation-info once for each page only
+ (nav (mapcar (lambda (hl)
+ (let* ((hl-number (alist-get hl stripped-section-headline-numbering))
+ (up (car (rassoc (butlast hl-number) stripped-section-headline-numbering))))
+ (list hl
+ (org-html-element-title hl)
+ (org-html--full-reference hl info t)
+ (org-html-element-title up)
+ (and up (org-html--full-reference up info t)))))
+ (plist-get info :section-trees))))
+ ;;; collect the info for prev, curr, next and up navigation for
+ ;;; each page by cdr-ing over nav.
+ (cl-labels ((inner (prev-entry curr-entry)
+ (let ((prev (car prev-entry))
+ (curr (car curr-entry))
+ (next (cadr curr-entry)))
+ (if curr
+ (cons (list (car curr)
+ :prev-title (nth 1 prev)
+ :curr-title (nth 1 curr)
+ :next-title (nth 1 next)
+ :up-title (nth 3 curr)
+ :prev-url (nth 2 prev)
+ :curr-url (nth 2 curr)
+ :next-url (nth 2 next)
+ :up-url (nth 4 curr))
+ (inner (cdr prev-entry) (cdr curr-entry)))))))
+ (inner (cons nil nav) nav))))
+
+ (defun org-html--make-multipage-toc-lookup (info)
+ "Return an assoc-list containing info for the headlines of all toc entries."
+ (mapcar
+ (lambda (hl)
+ (let* ((tl-hl (org-html-element-get-top-level hl)))
+ (list hl
+ :href (org-html--full-reference hl info (plist-get info :html-multipage-toc-to-top))
+ :tl-hl tl-hl
+ :relative-level (org-export-get-relative-level hl info)
+ :toc-body (org-html--get-toc-body hl info)
+ :toc-hl-number (alist-get hl (plist-get info :headline-numbering))
+ :page-hl-number (org-html-get-multipage-headline-number hl info))))
+ (org-html-collect-local-headlines info nil)))
+
+ (defun org-html-get-multipage-tl-headline (element info)
+ "return the headline of the page containing
+ element. This requires that :headline-numbering has already been
+ added to info (done in org-export--collect-tree-properties)."
+ (let* ((elem element)
+ (parent (org-element-property :parent elem)))
+ (while parent
+ (setf elem parent)
+ (setf parent (org-element-property :parent elem)))
+ elem))
+
+ (defun org-html-get-multipage-headline-numbering (element info)
+ "return the headline of the section containing
+ element. This requires that :headline-numbering has already been
+ added to info (done in org-export--collect-tree-properties)."
+ (let* ((elem element)
+ (parent (org-element-property :parent elem))
+ (hl-numbering (assoc elem (plist-get info :stripped-section-headline-numbering))))
+ (while (not hl-numbering)
+ (setf elem parent)
+ (setf parent (org-element-property :parent elem))
+ (setf hl-numbering (assoc elem (plist-get info :stripped-section-headline-numbering))))
+ hl-numbering))
+
+ (defun org-html-get-multipage-headline-number (element info)
+ "return the headline-number of the section containing
+ element. This requires that :headline-numbering has already been
+ added to info (done in org-export--collect-tree-properties)."
+ (cdr (org-html-get-multipage-headline-numbering element info)))
+
+ (defun org-html-element-get-top-level (element)
+ "Return the top-level element of ELEMENT by traversing the parse
+ tree upwards until the parent of element is nil."
+ (let ((elem element)
+ (parent (org-element-property :parent element)))
+ (while parent
+ (setq elem parent)
+ (setq parent (org-element-property :parent elem)))
+ elem))
+
+ (defun org-html-element-copy-element (org-node &optional keep-parent)
+ "copy ORG-NODE to a new org-node with elements not copied,
+ but referenced."
+ (let* (headline
+ (props (copy-sequence (nth 1 org-node)))
+ (new (list (car org-node) props)))
+ (unless keep-parent (setf (org-element-property :parent new) nil))
+ (apply 'org-element-adopt-elements new (org-element-contents org-node))))
+
+ (defun org-html-element-remove-subheadlines (org-node &optional
+ keep-first-subheadlines max-toc-depth keep-parent)
+ "remove all elements starting with and including the first headline
+ in the children of ORG-NODE if JOIN_EMPTY_BODIES is nil. Returns a
+ new ast with all elements starting at START-CHILD-IDX copied into
+ it with the :parent property optionally removed in the top node."
+ (let* ((num-subheadlines 0)
+ contents-end
+ headline
+ (props (copy-sequence (nth 1 org-node)))
+ (new (list (car org-node) props))
+ (new-children (cl-loop
+ for x in (org-element-contents org-node)
+ with exit = nil
+ do (if (and
+ (consp x)
+ (eq (org-element-type x) 'headline))
+ (if (and (car keep-first-subheadlines) (zerop num-subheadlines))
+ (progn
+ (setf num-subheadlines (1+ num-subheadlines))
+ (if (< (org-element-property :level x) max-toc-depth)
+ (setq x (org-html-element-remove-subheadlines
+ x (cdr keep-first-subheadlines) max-toc-depth))))
+ (progn
+ (setq contents-end (org-element-property :begin x))
+ (setq exit t))))
+ until exit
+ collect x)))
+ (unless keep-parent (setf (org-element-property :parent new) nil))
+ (apply 'org-element-adopt-elements new new-children)))
+
+ (defun org-html-find-headline (headline-number headline-numbering)
+ "return the headline in headline numbering for a given
+ headline-number."
+ (cond
+ ((null headline-numbering) nil)
+ ((equal headline-number (cdar headline-numbering))
+ (caar headline-numbering))
+ (t (org-html-find-headline headline-number (cdr headline-numbering)))))
+
+ (defun org-html-element-body-text (element info)
+ "check if transcoding of the contents of element until the next
+ subheadline returns an empty string."
+ (let ((strings
+ (cl-loop
+ for elem in (org-element-contents element)
+ while (not (eq 'headline (org-element-type elem)))
+ collect (org-export-data elem info))))
+ (string-trim
+ (apply 'concat
+ (with-temp-buffer
+ (mapcar 'insert strings)
+ (dom-strings (libxml-parse-html-region (point-min) (point-max))))))))
+
+ (defun org-html-element-body-text? (element info)
+ "check if transcoded element produces any text."
+ (not (eq "" (org-html-element-body-text element info))))
+
+ (defun org-html-page-headlines (headlines info)
+ "collect the headlines of all pages to export. In case of
+ html-multipage-join-empty-bodies don't collect the headlines to
+ be joined and keep track by collecting them for each page
+ headline in :keep-first-subhls.
+ `org-html-element-remove-subheadlines'"
+ (if (plist-get info :html-multipage-join-empty-bodies)
+ (cl-loop for (prev curr-headline) on (cons nil headlines)
+ with collect-hl = nil
+ with tmp = nil
+ with keep-shl = nil
+ while curr-headline
+ do (progn
+ (setf
+ collect-hl
+ (or ;; collect curr-headline either
+ (not prev) ;; when it is the first headline
+ (<= (length (cdr curr-headline))
+ (length (cdr prev))) ;; when it is not a subheadline of prev.
+ ;; or when the previous headline contains body text
+ (org-html-element-body-text? (car prev) info)))
+ (if collect-hl
+ (progn (push (reverse tmp) keep-shl)
+ (setf tmp nil))
+ (push t tmp)))
+ if collect-hl collect curr-headline
+ finally (progn (push tmp keep-shl)
+ (plist-put info :keep-first-subhls (cdr (reverse keep-shl)))))
+ headlines))
+
+ (defun org-html-transcode-org-page (page info)
+ "transcode the headline tree in the contents of the org-page
+ pseudo element PAGE into a string according to the backend and
+ return the string.
+
+ INFO is used as communication channel."
+ (let* ((body-only (org-element-property :body-only page))
+ (headline (org-element-property :tl-headline page))
+ (info (cl-list*
+ :tl-headline headline
+ :tl-headline-number (org-element-property :tl-headline-number page)
+ info))
+ (body (org-element-normalize-string
+ (or (org-export-data headline info)
+ "")))
+ (inner-template (if (plist-get info :multipage)
+ (alist-get 'multipage-inner-template
+ (plist-get info :translate-alist))
+ (alist-get 'inner-template
+ (plist-get info :translate-alist))))
+ (full-body (org-export-filter-apply-functions
+ (plist-get info :filter-body)
+ (if (not (functionp inner-template)) body
+ (funcall inner-template body info))
+ info))
+ (template (if (plist-get info :multipage)
+ (cdr (assq 'multipage-template
+ (plist-get info :translate-alist)))
+ (cdr (assq 'template
+ (plist-get info :translate-alist)))))
+ (output
+ (if (or (not (functionp template)) body-only) full-body
+ (funcall template full-body info))))
+ ;; Call citation export finalizer.
+ (setq output (org-cite-finalize-export output info))
+ ;; Remove all text properties since they cannot be
+ ;; retrieved from an external process. Finally call
+ ;; final-output filter and return result.
+ (org-no-properties
+ (org-export-filter-apply-functions
+ (plist-get info :filter-final-output)
+ output info))))
+
+ (defun org-html-export-to-multipage
+ (&optional async subtreep visible-only body-only ext-plist post-process)
+ "Export current buffer to multipage HTML files.
+
+ If narrowing is active in the current buffer, only export its
+ narrowed part.
+
+ If a region is active, export that region.
+
+ A non-nil optional argument ASYNC means the process should happen
+ asynchronously. The resulting files should be accessible through
+ the `org-export-stack' interface.
+
+ When optional argument SUBTREEP is non-nil, export the sub-tree
+ at point, extracting information from the headline properties
+ first.
+
+ When optional argument VISIBLE-ONLY is non-nil, don't export
+ contents of hidden elements.
+
+ When optional argument BODY-ONLY is non-nil, only write code
+ between \"<body>\" and \"</body>\" tags.
+
+ EXT-PLIST, when provided, is a property list with external
+ parameters overriding Org default settings, but still inferior to
+ file-local settings.
+
+ Return output directory's name."
+ (interactive)
+ (let* ((extension (concat
+ (when (> (length org-html-extension) 0) ".")
+ (or (plist-get ext-plist :html-extension)
+ org-html-extension
+ "html")))
+ (backend 'html)
+ (encoding (or org-export-coding-system buffer-file-coding-system))
+ (org-export-coding-system org-html-coding-system)
+ (environment (org-export-get-environment 'html nil nil))
+ (dir (org-html-multipage-ensure-export-dir
+ (plist-get environment :html-multipage-export-directory))))
+ (if (not (file-writable-p dir)) (error "Output dir not writable")
+ (progn
+ (message "collecting multipage output...")
+ (let ((output
+ (org-export-as backend subtreep visible-only body-only
+ (cl-list*
+ :async async
+ :multipage t
+ :verified-export-directory dir
+ ext-plist))))
+ (when (plist-get environment :html-multipage-clear-export-directory)
+ (message "clearing export-directory.")
+ (dolist
+ (file (directory-files dir nil ".html$"))
+ (delete-file (format "%s/%s" dir file))))
+ (dolist (out output)
+ (if async
+ (org-export-async-start
+ (lambda (file)
+ (org-export-add-to-stack (expand-file-name file) backend))
+ `(let ((file (get-text-property 0 :ouput-file out)))
+ (setq file (org-export--write-output output ',encoding))
+ (let ((post (lambda (f) (or (ignore-errors (funcall ',post-process f)) f))))
+ (if (listp file) (mapcar post file) (funcall post file)))))
+ (let (file)
+ (setq file (org-export--write-output out encoding))
+ (when (and (org-export--copy-to-kill-ring-p) (org-string-nw-p output))
+ (org-kill-new output))
+ ;; Get proper return value.
+ (let ((post (lambda (f)
+ (or (and (functionp post-process)
+ (funcall post-process f))
+ f))))
+ (if (listp file) (mapcar post file) (funcall post file))))))
+ (if (member system-type '(darwin gnu/linux gnu))
+ (shell-command (format "ln -s %s %s/index.html" (get-text-property 0 :output-file (car output)) dir)))
+ (message "done!\n")
+ (cl-case (plist-get environment :html-multipage-open)
+ ('browser (org-open-file (format "%s" (get-text-property 0 :output-file (car output)))))
+ ('buffer (find-file (format "%s" (get-text-property 0 :output-file (car output)))))))))))
+
+ (defun org-html--hidden-in-toc? (headline-number tl-headline-number)
+ "Check if the entry of HEADLINE-NUMBER should be hidden in the
+ toc of the page containing TL-HEADLINE-NUMBER."
+ (and
+ (> (length headline-number) 1)
+ (let ((l1 (length headline-number))
+ (l2 (length tl-headline-number)))
+ (cond
+ ((= l1 l2) (not (equal (butlast headline-number)
+ (butlast tl-headline-number))))
+ ((> l1 l2) (not (equal tl-headline-number
+ (butlast headline-number))))
+ (t (not (equal (butlast headline-number)
+ (butlast (butlast tl-headline-number)))))))))
+
+ (defun org-html-collect-local-headlines (info scope)
+ "Collect all headlines of headline-numbering from their local
+ tl-headlines counterparts."
+ (let ((stripped-section-headline-numbering (plist-get info :stripped-section-headline-numbering))
+ (headline-numbering (plist-get info :headline-numbering)))
+ (mapcar
+ (lambda (global-headline)
+ (car
+ (rassoc (cdr (assoc global-headline headline-numbering))
+ stripped-section-headline-numbering)))
+ (org-export-collect-headlines
+ info
+ (if (numberp (plist-get info :with-toc))
+ (plist-get info :with-toc)
+ (plist-get info :headline-levels))
+ scope))))
+
+ (defun org-html-nav-left (nav-lookup)
+ "Return nav string for multipage Navigation in page-main-body.
+
+ INFO is a plist used as a communication channel.
+ "
+ (let* ((prev-url (plist-get nav-lookup :prev-url))
+ (prev-title (plist-get nav-lookup :prev-title)))
+ (if prev-url
+ (format "<nav id=\"nav-left\"><a href=\"%s\" class=\"nav-left\"><i class=\"angle-left\"></i></a></nav>"
+ prev-url)
+ (format "<nav id=\"nav-left\"><a href=\"%s\" class=\"nav-left\"><i class=\"angle-left-inactive\"></i></a></nav>"
+ ""))))
+
+ (defun org-html-nav-right (nav-lookup)
+ "Return nav string for multipage Navigation in page-main-body.
+
+ INFO is a plist used as a communication channel.
+ "
+ (let* ((next-url (plist-get nav-lookup :next-url))
+ (next-title (plist-get nav-lookup :next-title)))
+ (if next-url
+ (format "<nav id=\"nav-right\"><a href=\"%s\" class=\"nav-right\"><i class=\"angle-right\"></i></a></nav>"
+ next-url)
+ (format "<nav id=\"nav-right\"><a href=\"%s\" class=\"nav-right\"><i class=\"angle-right-inactive\"></i></a></nav>"
+ ""))))
+
+ (defun org-html-multipage-nav (info)
+ "Return the string for the multipage navigation anchors.
+
+ INFO is a plist used as a communication channel.
+ "
+ (let ((section-nav-lookup
+ (alist-get
+ (plist-get info :tl-headline)
+ (plist-get info :section-nav-lookup)))
+ (nav-format (plist-get info :html-multipage-nav-format)))
+ (format (car nav-format)
+ (concat
+ (when (plist-get section-nav-lookup :next-url)
+ (format (cadr nav-format)
+ (plist-get section-nav-lookup :next-url)
+ (plist-get section-nav-lookup :next-title)))
+ (when (plist-get section-nav-lookup :prev-url)
+ (format (caddr nav-format)
+ (plist-get section-nav-lookup :prev-url)
+ (plist-get section-nav-lookup :prev-title)))
+ (when (plist-get section-nav-lookup :up-url)
+ (format (cadddr nav-format)
+ (plist-get section-nav-lookup :up-url)
+ (plist-get section-nav-lookup :up-title)))
+ (when (plist-get info :html-top-url)
+ (format (nth 4 nav-format)
+ (plist-get info :html-top-url)
+ (plist-get info :html-top-title)))))))
+
+ (defun org-html-multipage-template (contents info)
+ "Return complete document string after HTML conversion.
+ CONTENTS is the transcoded contents string. INFO is a plist
+ holding export options."
+ (concat
+ (when (and (not (org-html-html5-p info)) (org-html-xhtml-p info))
+ (let* ((xml-declaration (plist-get info :html-xml-declaration))
+ (decl (or (and (stringp xml-declaration) xml-declaration)
+ (cdr (assoc (plist-get info :html-extension)
+ xml-declaration))
+ (cdr (assoc "html" xml-declaration))
+ "")))
+ (when (not (or (not decl) (string= "" decl)))
+ (format "%s\n"
+ (format decl
+ (or (and org-html-coding-system
+ ;; FIXME: Use Emacs 22 style here, see `coding-system-get'.
+ (coding-system-get org-html-coding-system 'mime-charset))
+ "iso-8859-1"))))))
+ (org-html-doctype info)
+ "\n"
+ (concat "<html"
+ (cond ((org-html-xhtml-p info)
+ (format
+ " xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\""
+ (plist-get info :language) (plist-get info :language)))
+ ((org-html-html5-p info)
+ (format " lang=\"%s\"" (plist-get info :language))))
+ ">\n")
+ "<head>\n"
+ (org-html--build-meta-info info)
+ (org-html--build-head info)
+ (org-html--build-mathjax-config info)
+ "</head>\n"
+ "<body>\n"
+ (when (eq org-html-multipage-preamble-position 'top)
+ (org-html--build-pre/postamble 'preamble info))
+ (org-html-multipage-nav info)
+ ;; Preamble.
+ (unless (eq org-html-multipage-preamble-position 'top)
+ (org-html--build-pre/postamble 'preamble info))
+ ;; Document contents.
+ (let ((div (assq 'content (plist-get info :html-divs))))
+ (format "<%s id=\"%s\" class=\"%s\">\n"
+ (nth 1 div)
+ (nth 2 div)
+ (plist-get info :html-content-class)))
+ ;; Table of contents.
+ (let ((depth (if (numberp (plist-get info :with-toc))
+ (plist-get info :with-toc)
+ (plist-get info :headline-levels))))
+ (when depth (org-html-multipage-toc depth info)))
+ ;; Document title.
+ (when (plist-get info :with-title)
+ (let ((title (and (plist-get info :with-title)
+ (plist-get info :title)))
+ (subtitle (plist-get info :subtitle))
+ (html5-fancy (org-html--html5-fancy-p info)))
+ (when title
+ (format
+ (if html5-fancy
+ "<header>\n<h1 class=\"title\">%s</h1>\n%s</header>"
+ "<h1 class=\"title\">%s%s</h1>\n")
+ (org-export-data title info)
+ (if subtitle
+ (format
+ (if html5-fancy
+ "<p class=\"subtitle\" role=\"doc-subtitle\">%s</p>\n"
+ (concat "\n" (org-html-close-tag "br" nil info) "\n"
+ "<span class=\"subtitle\">%s</span>\n"))
+ (org-export-data subtitle info))
+ "")))))
+ contents
+ (format "</%s>\n" (nth 1 (assq 'content (plist-get info :html-divs))))
+ ;; Possibly use the Klipse library live code blocks.
+ (when (plist-get info :html-klipsify-src)
+ (concat "<script>" (plist-get info :html-klipse-selection-script)
+ "</script><script src=\""
+ org-html-klipse-js
+ "\"></script><link rel=\"stylesheet\" type=\"text/css\" href=\""
+ org-html-klipse-css "\"/>"))
+ (when (eq org-html-multipage-postamble-position 'bottom)
+ (org-html--build-pre/postamble 'postamble info))
+ ;; Closing document.
+ "</body>\n</html>"))
+
+ (defun org-html-multipage-inner-template (contents info)
+ "Return body of document string after HTML conversion.
+ CONTENTS is the transcoded contents string. INFO is a plist
+ holding export options.
+
+ DATA contains the subtree of the parse tree of the section to be
+ exported for multipage export.
+ "
+ ;; Navigation
+ (let* ((data (plist-get info :tl-headline))
+ (section-nav-lookup
+ (alist-get
+ data
+ (plist-get info :section-nav-lookup))))
+ (format "<div id=\"page-main-body\">%s\n<div id=\"page-text-body\">%s</div>%s</div>"
+ (org-html-nav-left section-nav-lookup)
+ (concat
+ ;; Document contents.
+ contents
+ ;; Footnotes section.
+ (or (org-html-footnote-section info) "")
+ ;; Postamble.
+ (unless (eq org-html-multipage-postamble-position 'bottom)
+ (org-html--build-pre/postamble 'postamble info)))
+ (org-html-nav-right section-nav-lookup))))
+
+ (defun org-html-transcode-org-data (data content info)
+ "Transcode the top org-data node of the org file to export.
+
+ It is called by `org-export-as' after all necessary information
+ has been added to info and the final parse-tree has been
+ generated. Multipage information has already been collected by
+ calling `org-html-multipage-filter' in `org-export-annotate-info'
+ using the :multipage-split property.
+
+ INFO is a plist used as a communication channel."
+ (message "transcoding data!")
+ (if (plist-get info :multipage)
+ ;;; for multipage output we don't need data and content as all
+ ;;; information is already collected in info.
+ (org-html-transcode-multipage info)
+ (org-export-transcode-org-data data content info)))
(provide 'ox-html)
***************
*** 4100,4102 ****
--- 5485,5489 ----
;; End:
;;; ox-html.el ends here
+
+
[-- Attachment #5: org-manual.org.patch --]
[-- Type: text/plain, Size: 16184 bytes --]
*** org-mode/doc/org-manual.org 2024-08-05 17:15:57.585261838 +0200
--- org-mode-multipage/doc/org-manual.org 2024-08-05 15:40:24.679134249 +0200
***************
*** 772,781 ****
where you can use the following keys to find your destination:
#+attr_texinfo: :columns 0.3 0.7
! | {{{kbd(TAB)}}} | Cycle visibility. |
| {{{kbd(DOWN)}}} / {{{kbd(UP)}}} | Next/previous visible headline. |
! | {{{kbd(RET)}}} | Select this location. |
! | {{{kbd(/)}}} | Do a Sparse-tree search |
#+texinfo: @noindent
The following keys work if you turn off ~org-goto-auto-isearch~
--- 772,781 ----
where you can use the following keys to find your destination:
#+attr_texinfo: :columns 0.3 0.7
! | {{{kbd(TAB)}}} | Cycle visibility. |
| {{{kbd(DOWN)}}} / {{{kbd(UP)}}} | Next/previous visible headline. |
! | {{{kbd(RET)}}} | Select this location. |
! | {{{kbd(/)}}} | Do a Sparse-tree search |
#+texinfo: @noindent
The following keys work if you turn off ~org-goto-auto-isearch~
***************
*** 783,791 ****
#+attr_texinfo: :columns 0.3 0.7
| {{{kbd(n)}}} / {{{kbd(p)}}} | Next/previous visible headline. |
| {{{kbd(f)}}} / {{{kbd(b)}}} | Next/previous headline same level. |
! | {{{kbd(u)}}} | One level up. |
| {{{kbd(0)}}} ... {{{kbd(9)}}} | Digit argument. |
! | {{{kbd(q)}}} | Quit. |
#+vindex: org-goto-interface
#+texinfo: @noindent
--- 783,791 ----
#+attr_texinfo: :columns 0.3 0.7
| {{{kbd(n)}}} / {{{kbd(p)}}} | Next/previous visible headline. |
| {{{kbd(f)}}} / {{{kbd(b)}}} | Next/previous headline same level. |
! | {{{kbd(u)}}} | One level up. |
| {{{kbd(0)}}} ... {{{kbd(9)}}} | Digit argument. |
! | {{{kbd(q)}}} | Quit. |
#+vindex: org-goto-interface
#+texinfo: @noindent
***************
*** 2044,2050 ****
#+attr_texinfo: :columns 0.2 0.8
| =$1..$3= | first three fields in the current row |
! | =$P..$Q= | range, using column names (see [[*Advanced features]]) |
| =$<<<..$>>= | start in third column, continue to the last but one |
| =@2$1..@4$3= | nine fields between these two fields (same as =A2..C4=) |
| =@-1$-2..@-1= | 3 fields in the row above, starting from 2 columns on the left |
--- 2044,2050 ----
#+attr_texinfo: :columns 0.2 0.8
| =$1..$3= | first three fields in the current row |
! | =$P..$Q= | range, using column names (see [[*Advanced features]]) |
| =$<<<..$>>= | start in third column, continue to the last but one |
| =@2$1..@4$3= | nine fields between these two fields (same as =A2..C4=) |
| =@-1$-2..@-1= | 3 fields in the row above, starting from 2 columns on the left |
***************
*** 2248,2255 ****
| =$1+$2;%.2f= | Same, format result to two decimals |
| =exp($2)+exp($1)= | Math functions can be used |
| =$0;%.1f= | Reformat current cell to 1 decimal |
! | =($3-32)*5/9= | Degrees F \to C conversion |
! | =$c/$1/$cm= | Hz \to cm conversion, using =constants.el= |
| =tan($1);Dp3s1= | Compute in degrees, precision 3, display SCI 1 |
| =sin($1);Dp3%.1e= | Same, but use ~printf~ specifier for display |
| =vmean($2..$7)= | Compute column range mean, using vector function |
--- 2248,2255 ----
| =$1+$2;%.2f= | Same, format result to two decimals |
| =exp($2)+exp($1)= | Math functions can be used |
| =$0;%.1f= | Reformat current cell to 1 decimal |
! | =($3-32)*5/9= | Degrees F \to C conversion |
! | =$c/$1/$cm= | Hz \to cm conversion, using =constants.el= |
| =tan($1);Dp3s1= | Compute in degrees, precision 3, display SCI 1 |
| =sin($1);Dp3%.1e= | Same, but use ~printf~ specifier for display |
| =vmean($2..$7)= | Compute column range mean, using vector function |
***************
*** 11995,12001 ****
#+attr_texinfo: :columns 0.1 0.9
| {{{kbd(s)}}} | Sort the footnote definitions by reference sequence. |
| {{{kbd(r)}}} | Renumber the simple =fn:N= footnotes. |
! | {{{kbd(S)}}} | Short for first {{{kbd(r)}}}, then {{{kbd(s)}}} action. |
| {{{kbd(n)}}} | Rename all footnotes into a =fn:1= ... =fn:n= sequence. |
| {{{kbd(d)}}} | Delete the footnote at point, including definition and references. |
--- 11995,12001 ----
#+attr_texinfo: :columns 0.1 0.9
| {{{kbd(s)}}} | Sort the footnote definitions by reference sequence. |
| {{{kbd(r)}}} | Renumber the simple =fn:N= footnotes. |
! | {{{kbd(S)}}} | Short for first {{{kbd(r)}}}, then {{{kbd(s)}}} action. |
| {{{kbd(n)}}} | Rename all footnotes into a =fn:1= ... =fn:n= sequence. |
| {{{kbd(d)}}} | Delete the footnote at point, including definition and references. |
***************
*** 13283,13288 ****
--- 13283,13299 ----
Exports to a temporary buffer. Does not create a file.
+ - {{{kbd(C-c C-e h m)}}} (~org-html-export-to-multipage~) ::
+ #+kindex: C-c C-e h m
+ #+findex: org-html-export-to-multipage
+
+ Export as multiple HTML files with a =.html= extension. The
+ exported files are written into a directory specified with the
+ customization variable =org-html-multipage-export-dir=. If
+ =org-html-clear-export-directory= is non-nil, all files with a
+ =.html= extension will be removed before writing the files. Files
+ with duplicate names will be overwritten without warning.
+
*** HTML specific export settings
:PROPERTIES:
:DESCRIPTION: Settings for HTML export.
***************
*** 13823,13831 ****
#+vindex: org-html-head-extra
#+cindex: @samp{HTML_INCLUDE_STYLE}, keyword
The HTML export backend includes a compact default style in each
! exported HTML file. To override the default style with another style,
! use these keywords in the Org file. They will replace the global
! defaults the HTML exporter uses.
#+cindex: @samp{HTML_HEAD}, keyword
#+cindex: @samp{HTML_HEAD_EXTRA}, keyword
--- 13834,13844 ----
#+vindex: org-html-head-extra
#+cindex: @samp{HTML_INCLUDE_STYLE}, keyword
The HTML export backend includes a compact default style in each
! exported HTML file[fn:: The constant is called
! ~org-html-style-default~ for single page output and
! ~org-html-multipage-style-default~ for multipage output]. To override
! the default style with another style, use these keywords in the Org
! file. They will replace the global defaults the HTML exporter uses.
#+cindex: @samp{HTML_HEAD}, keyword
#+cindex: @samp{HTML_HEAD_EXTRA}, keyword
***************
*** 13855,13861 ****
a =CUSTOM_ID= property. You can also assign a specific class to
a headline with the =HTML_HEADLINE_CLASS= property.
! Never change the ~org-html-style-default~ constant. Instead, use other
simpler ways of customizing as described above.
*** JavaScript supported display of web pages
--- 13868,13875 ----
a =CUSTOM_ID= property. You can also assign a specific class to
a headline with the =HTML_HEADLINE_CLASS= property.
! Never change the ~org-html-style-default~ and
! ~org-html-multipage-style-default~ constants. Instead, use other
simpler ways of customizing as described above.
*** JavaScript supported display of web pages
***************
*** 13944,13949 ****
--- 13958,14124 ----
variable ~org-infojs-options~. If you always want to apply the script
to your pages, configure the variable ~org-export-html-use-infojs~.
+ *** Multipage HTML specific export options
+ The options and custom variables for HTML export also apply to
+ multipage export. In addition the variables below are applying to
+ multipage export. They can be set using the listed variable name
+ or using an in buffer option using the name without the =org-= at
+ the beginning as in the following example:
+ #+begin_src
+ #+OPTIONS: html-multipage-clear-export-directory:t
+ #+end_src
+
+ - ~org-html-multipage-clear-export-directory~ ::
+
+ #+vindex: org-html-multipage-clear-export-directory
+ Whether to clear all =.html= files in the export directory before
+ writing.
+
+ - ~org-html-multipage-export-directory~ ::
+
+ #+vindex: org-html-multipage-export-directory
+ The directory where the multiple files will be written. Relative to
+ the path of the Org document or absolute.
+
+ - ~org-html-multipage-head-include-default-style~ ::
+
+ #+vindex: org-html-multipage-head-include-default-style
+ Whether to include the default CSS style
+ (=org-html-multipage-style-default=) into every exported file.
+
+ - ~org-html-multipage-join-empty-bodies~ ::
+
+ #+vindex: org-html-multipage-join-empty-bodies
+ Recursively join subheadlines, if a headline doesn't contain any
+ text before its subheadline.
+
+ Example:
+ #+begin_example
+ ,* Headline 1
+ ,** Subheadline 1.1
+ ,*** Subsubheadline 1.1.1
+ Text of Subsubheadline 1.1.1
+ #+end_example
+ will be put on the same HTML page if this option is set, otherwise
+ Headline 1 and Subheadline 1.1 will each be put on a separate HTML
+ page with empty content.
+
+ - ~org-html-multipage-nav-format~ ::
+
+ #+vindex: org-html-multipage-nav-format
+ The HTML format string for the four navigation elements in the top
+ navigation menu of each page. See explanation of the variable
+ ~org-html-multipage-nav-format~.
+
+ - ~org-html-multipage-numbered-filenames~ ::
+
+ #+vindex: org-html-multipage-numbered-filenames
+ Boolean indicating whether filenames in multipage export should get
+ their headline-numbering prepended. Note that this option is
+ independent of the =num:= option and that the backend guarantees
+ that filenames are unique in any case.
+
+ - ~org-html-multipage-open~ ::
+
+ #+vindex: org-html-multipage-open
+ If and where to open the top page of the multipage html after
+ export. Possible values are =browser=, =buffer= or =nil=. Note that
+ all files will always be written, even for the =buffer= case.
+
+ - ~org-html-multipage-postamble-position~ ::
+
+ #+vindex: org-html-multipage-postamble-position
+ The position of the postamble in the html output.
+ Possible choices are =bottom= or =text-content=.
+ See [[*Multipage HTML specific CSS support]]
+
+ - ~org-html-multipage-preamble-position~ ::
+
+ #+vindex: org-html-multipage-preamble-position
+ The position of the postamble in the html output.
+ Possible choices are =top= or =text-content=.
+ See [[*Multipage HTML specific CSS support]]
+
+ - ~org-html-multipage-split-hooks~ ::
+
+ #+vindex: org-html-multipage-split-hooks
+ list of additional custom functions to be called during the export
+ after multipage splitting has taken place and before transcoding
+ with the =info= communication channel as input.
+
+ - ~org-html-multipage-split-level~ ::
+
+ #+vindex: org-html-multipage-split-level
+ Where to split the ORG file into multiple HTML pages. Can be either
+ =toc= for splitting into a separate page for each toc entry or a
+ number defining the maximum headline level for splitting.
+
+ - ~org-html-multipage-toc-to-top~ ::
+
+ #+vindex: org-html-multipage-toc-to-top
+ If t links in the table of contents will always point to the top of
+ the referenced page, otherwise it will link directly to the
+ referenced headline element.
+
+ *** Multipage HTML specific CSS support
+ :PROPERTIES:
+ :DESCRIPTION: Changing the appearance of the Multipage HTML output.
+ :END:
+ #+cindex: CSS, for Multipage HTML export
+ #+cindex: HTML Multipage export, CSS
+
+ #+vindex: org-html-multipage-preamble-position
+ #+vindex: org-html-multipage-preamble-position
+ #+vindex: org-html-multipage-postamble-position
+ In HTML multipage output each page will be generated with the
+ following structure:
+
+ #+begin_example
+ ,* html
+ ,** head
+ ,** body
+ ,*** preamble
+ ,*** org-div-nav-menu
+ ,*** content
+ ,**** table-of-contents
+ ,**** page-main-body
+ ,***** nav-left
+ ,***** page-text-body
+ ,***** nav-right
+ ,*** postamble
+ #+end_example
+
+ The default CSS shipped with org-mode will place a table of contents
+ to the left of the page content below the preamble and the top
+ navigation menu. This table of contents will contain /all/ headlines
+ according to the =toc= option, ignoring any =notoc= option within the
+ document to make every exported page of the document accessible.
+
+ Preamble and postamble can be moved inside the page text body at its
+ top and bottom using =org-html-multipage-preamble-position= and
+ =org-html-multipage-postamble-position= respectively. Elements to be
+ skipped can be hidden by setting their =display= property to =none= in
+ the CSS. Note that the table of contents will only be generated if
+
+ In addition to the single page HTML CSS support (see [[*CSS support]])
+ the HTML Multipage exporter assigns the following special CSS classes
+ to appropriate parts of the document. They are mainly concerned with
+ navigation elements. The table of contents CSS below refers to the
+ table of contents generated for every page of the multipage HTML
+ output and /not/ to any additional toc inside the text body.
+
+ | ~#org-div-nav-menu~ | Top Navigation Menu |
+ | ~#table-of-contents~ | the Table of Contents generated for every output page |
+ | ~#text-table-of-contents~ | the Table of Contents text area after its title |
+ | ~.ul-toc-level-N~ | the ul element of a toc entry with level N. |
+ | ~.toc-level-N~ | the li element of a toc entry with level N. |
+ | ~.toc-hidden~ | the li element of a toc entry to be (optionally) hidden |
+ | ~.toc-entry~ | the a element of a toc entry. |
+ | ~.toc-entry-active~ | The anchor of the toc entry currently active. |
+ | ~#nav-left~ | Navigation contained in the page-main-body div to the previous page. |
+ | ~#nav-right~ | Navigation contained in the page-main-body div to the next page |
+ | | |
+
** LaTeX Export
:PROPERTIES:
:DESCRIPTION: Exporting to @LaTeX{} and processing to PDF.
***************
*** 16655,16666 ****
:UNNUMBERED: notoc
:END:
! The Org export can filter not just for backends, but also for
! specific files through the =BIND= keyword. Here is an example with
! two filters; one removes brackets from time stamps, and the other
! removes strike-through text. The filter functions are defined in
! a code block in the same Org file, which is a handy location for
! debugging.
#+begin_example
,#+BIND: org-export-filter-timestamp-functions (tmp-f-timestamp)
--- 16830,16842 ----
:UNNUMBERED: notoc
:END:
! The Org export can filter not just for backends, but also for specific
! files through the =BIND= keyword. Here is an example with two
! filters; one removes brackets from time stamps, and the other removes
! strike-through text. The filter functions are defined in a code block
! in the same Org file, which is a handy location for debugging. Note
! that ~org-export-allow-bind-keywords~ has to be non-nil for this to
! work.
#+begin_example
,#+BIND: org-export-filter-timestamp-functions (tmp-f-timestamp)
next prev parent reply other threads:[~2024-08-05 16:53 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-03 9:44 multipage html output Orm Finnendahl
2024-07-03 10:33 ` Dr. Arne Babenhauserheide
2024-07-03 10:58 ` Christian Moe
2024-07-03 11:05 ` Ihor Radchenko
2024-07-03 14:34 ` Christian Moe
2024-07-04 9:50 ` Orm Finnendahl
2024-07-04 11:41 ` Ihor Radchenko
2024-07-04 13:33 ` Orm Finnendahl
2024-07-04 16:20 ` Ihor Radchenko
2024-07-07 19:33 ` Orm Finnendahl
2024-07-08 15:29 ` Ihor Radchenko
2024-07-08 19:12 ` Orm Finnendahl
2024-07-09 17:55 ` Ihor Radchenko
2024-07-10 18:03 ` Orm Finnendahl
2024-07-10 18:53 ` Ihor Radchenko
2024-07-07 20:50 ` Orm Finnendahl
2024-07-08 15:05 ` Ihor Radchenko
2024-07-08 15:41 ` Orm Finnendahl
2024-07-08 15:56 ` Ihor Radchenko
2024-07-08 19:18 ` Orm Finnendahl
2024-07-09 18:08 ` Ihor Radchenko
2024-07-10 19:37 ` Orm Finnendahl
2024-07-11 12:35 ` Ihor Radchenko
2024-07-13 7:44 ` Orm Finnendahl
2024-07-13 10:13 ` Ihor Radchenko
2024-07-13 11:01 ` Orm Finnendahl
2024-07-23 8:56 ` Orm Finnendahl
2024-07-23 10:24 ` Ihor Radchenko
2024-07-23 11:35 ` Orm Finnendahl
2024-07-23 12:52 ` Ihor Radchenko
2024-07-23 14:56 ` Orm Finnendahl
[not found] ` <Zp_EhDDxxYRWKFPL@orm-t14s>
[not found] ` <874j8g2lvq.fsf@localhost>
2024-07-23 15:36 ` Orm Finnendahl
2024-07-23 14:13 ` Ihor Radchenko
[not found] ` <Zp_b2lL2SzDswa-w@orm-t14s>
2024-07-23 17:10 ` Ihor Radchenko
2024-07-23 20:35 ` Orm Finnendahl
2024-07-24 10:20 ` Ihor Radchenko
2024-07-24 11:24 ` Orm Finnendahl
2024-07-25 9:49 ` Orm Finnendahl
2024-07-25 9:57 ` Ihor Radchenko
2024-07-25 9:57 ` Orm Finnendahl
2024-07-25 10:04 ` Ihor Radchenko
2024-07-25 14:59 ` Orm Finnendahl
2024-07-27 19:24 ` Orm Finnendahl
2024-07-27 19:39 ` Ihor Radchenko
2024-08-05 16:52 ` Orm Finnendahl [this message]
2024-08-05 18:22 ` Ihor Radchenko
2024-08-06 7:19 ` Orm Finnendahl
2024-08-06 18:47 ` Orm Finnendahl
2024-08-06 20:04 ` Orm Finnendahl
2024-08-10 12:32 ` Ihor Radchenko
2024-08-11 10:54 ` Orm Finnendahl
2024-08-11 13:47 ` Ihor Radchenko
2024-08-11 14:44 ` Orm Finnendahl
2024-08-12 8:35 ` Orm Finnendahl
2024-08-12 17:10 ` Ihor Radchenko
2024-08-12 18:58 ` Orm Finnendahl
2024-08-17 7:21 ` Rudolf Adamkovič
2024-08-17 14:05 ` Ihor Radchenko
2024-08-19 16:31 ` Orm Finnendahl
2024-08-22 12:27 ` Ihor Radchenko
2024-07-26 8:22 ` Orm Finnendahl
2024-07-27 13:01 ` Ihor Radchenko
2024-07-27 14:25 ` Orm Finnendahl
2024-07-23 14:19 ` Ihor Radchenko
2024-07-23 15:13 ` Orm Finnendahl
2024-07-23 16:20 ` Ihor Radchenko
2024-07-23 17:02 ` Orm Finnendahl
2024-07-23 17:13 ` Ihor Radchenko
2024-07-23 19:00 ` Orm Finnendahl
2024-07-03 21:11 ` Rudolf Adamkovič
-- strict thread matches above, loose matches on Subject: below --
2024-07-06 5:47 Pedro Andres Aranda Gutierrez
2024-07-06 9:04 ` Orm Finnendahl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZrEDMt_gbf5oBTJB@orm-t14s \
--to=orm.finnendahl@selma.hfmdk-frankfurt.de \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).