update of packages
This commit is contained in:
98
lisp/ox-tufte/ox-tufte-autoloads.el
Normal file
98
lisp/ox-tufte/ox-tufte-autoloads.el
Normal file
@@ -0,0 +1,98 @@
|
||||
;;; ox-tufte-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||
;; Generated by the `loaddefs-generate' function.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||
|
||||
|
||||
|
||||
;;; Generated autoloads from ox-tufte.el
|
||||
|
||||
(autoload 'org-tufte-export-as-html "ox-tufte" "\
|
||||
Export current buffer to a Tufte HTML buffer.
|
||||
|
||||
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 buffer 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.
|
||||
|
||||
Export is done in a buffer named \"*Org Tufte Export*\", which will
|
||||
be displayed when `org-export-show-temporary-export-buffer' is
|
||||
non-nil.
|
||||
|
||||
(fn &optional ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY EXT-PLIST)" t)
|
||||
(autoload 'org-tufte-export-to-html "ox-tufte" "\
|
||||
Export current buffer to a Tufte HTML file.
|
||||
|
||||
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 file 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 file's name.
|
||||
|
||||
(fn &optional ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY EXT-PLIST)" t)
|
||||
(autoload 'org-tufte-publish-to-html "ox-tufte" "\
|
||||
Publish an org file to Tufte-styled HTML.
|
||||
|
||||
PLIST is the property list for the given project. FILENAME is
|
||||
the filename of the Org file to be published. PUB-DIR is the
|
||||
publishing directory.
|
||||
|
||||
Return output file name.
|
||||
|
||||
(fn PLIST FILENAME PUB-DIR)")
|
||||
(register-definition-prefixes "ox-tufte" '("org-tufte-" "ox-tufte--"))
|
||||
|
||||
;;; End of scraped data
|
||||
|
||||
(provide 'ox-tufte-autoloads)
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; no-native-compile: t
|
||||
;; coding: utf-8-emacs-unix
|
||||
;; End:
|
||||
|
||||
;;; ox-tufte-autoloads.el ends here
|
||||
9
lisp/ox-tufte/ox-tufte-pkg.el
Normal file
9
lisp/ox-tufte/ox-tufte-pkg.el
Normal file
@@ -0,0 +1,9 @@
|
||||
(define-package "ox-tufte" "20231022.2117" "Tufte HTML org-mode export backend"
|
||||
'((org "9.5")
|
||||
(emacs "27.1"))
|
||||
:commit "58422fb109f2b2a997f9c773b5436e7b62182e12" :keywords
|
||||
'("org" "tufte" "html" "outlines" "hypermedia" "calendar" "wp")
|
||||
:url "https://github.com/ox-tufte/ox-tufte")
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
526
lisp/ox-tufte/ox-tufte.el
Normal file
526
lisp/ox-tufte/ox-tufte.el
Normal file
@@ -0,0 +1,526 @@
|
||||
;;; ox-tufte.el --- Tufte HTML org-mode export backend -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2023 The Bayesians Inc.
|
||||
;; Copyright (C) 2016-2022 Matthew Lee Hinman
|
||||
|
||||
;; Author: The Bayesians Inc.
|
||||
;; M. Lee Hinman
|
||||
;; Maintainer: The Bayesians Inc.
|
||||
;; Description: An org exporter for Tufte HTML
|
||||
;; Keywords: org, tufte, html, outlines, hypermedia, calendar, wp
|
||||
;; Version: 3.0.3
|
||||
;; Package-Requires: ((org "9.5") (emacs "27.1"))
|
||||
;; URL: https://github.com/ox-tufte/ox-tufte
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This is an export backend for Org-mode that exports buffers to HTML that
|
||||
;; is compatible with Tufte CSS - <https://edwardtufte.github.io/tufte-css/>.
|
||||
;; The design goal is to "minimally" change the HTML structure as generated by
|
||||
;; `ox-html' (with additional CSS as needed) to get behaviour that is equivalent
|
||||
;; to Tufte CSS.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ox)
|
||||
(require 'ox-html)
|
||||
(eval-when-compile (require 'cl-lib)) ;; for cl-assert
|
||||
|
||||
(org-babel-lob-ingest
|
||||
(concat (file-name-directory (locate-library "ox-tufte")) "src/README.org"))
|
||||
|
||||
|
||||
;;; User-Configurable Variables
|
||||
|
||||
(defgroup org-export-tufte nil
|
||||
"Options for exporting Org mode files to Tufte-CSS themed HTML."
|
||||
:tag "Org Export Tufte HTML"
|
||||
:group 'org-export)
|
||||
|
||||
(defcustom org-tufte-feature-more-expressive-inline-marginnotes t
|
||||
"Non-nil enables marginnote-as-macro and marginnote-as-babelcall syntax."
|
||||
:group 'org-export-tufte
|
||||
:type 'boolean
|
||||
:safe #'booleanp)
|
||||
|
||||
(defcustom org-tufte-include-footnotes-at-bottom nil
|
||||
"Non-nil means to include footnotes at the bottom of the page.
|
||||
This is in addition to being included as sidenotes. Sidenotes are not shown on
|
||||
very narrow screens (phones), so it may be useful to additionally include them
|
||||
at the bottom."
|
||||
:group 'org-export-tufte
|
||||
:type 'boolean
|
||||
:safe #'booleanp)
|
||||
|
||||
(defcustom org-tufte-margin-note-symbol "⊕"
|
||||
"The symbol that is used as a viewability-toggle on small screens."
|
||||
:group 'org-export-tufte
|
||||
:type 'string
|
||||
:safe #'stringp)
|
||||
|
||||
(defcustom org-tufte-randid-limit 10000000
|
||||
"Upper limit when generating random IDs.
|
||||
|
||||
With default value of 10000000, there is ~0.2% chance of collision with 200
|
||||
references."
|
||||
:group 'org-export-tufte
|
||||
:type 'integer
|
||||
:safe #'integerp)
|
||||
|
||||
|
||||
;;; Define Back-End
|
||||
(org-export-define-derived-backend 'tufte-html 'html
|
||||
:menu-entry
|
||||
'(?T "Export to Tufte-HTML"
|
||||
((?H "As HTML buffer" org-tufte-export-as-html)
|
||||
(?h "As HTML file" org-tufte-export-to-html)
|
||||
(?o "As HTML file and open"
|
||||
(lambda (a s v b)
|
||||
(if a (org-tufte-export-to-html t s v b)
|
||||
(org-open-file (org-tufte-export-to-html nil s v b)))))))
|
||||
:options-alist
|
||||
'((:footnotes-section-p nil "footnotes-section-p"
|
||||
org-tufte-include-footnotes-at-bottom))
|
||||
:translate-alist '((footnote-reference . org-tufte-footnote-reference)
|
||||
;; (src-block . org-tufte-src-block)
|
||||
(link . org-tufte-maybe-margin-note-link)
|
||||
(quote-block . org-tufte-quote-block)
|
||||
(special-block . org-tufte-special-block)
|
||||
(verse-block . org-tufte-verse-block)))
|
||||
|
||||
|
||||
;;; Utility Functions
|
||||
|
||||
(defun ox-tufte--utils-filter-ptags (str)
|
||||
"Remove <p> tags from STR.
|
||||
|
||||
Sidenotes and margin notes must have <p> and </p> tags removed to conform with
|
||||
the html structure that tufte.css expects."
|
||||
(replace-regexp-in-string "</?p.*?>" "" str))
|
||||
|
||||
(defun ox-tufte--utils-footnotes-section ()
|
||||
"Toggle Footnotes section HTML based on `org-tufte-include-footnotes-at-bottom'."
|
||||
(if org-tufte-include-footnotes-at-bottom
|
||||
org-html-footnotes-section
|
||||
"<!-- %s --><!-- %s -->"))
|
||||
|
||||
(defconst ox-tufte--utils-macros-alist
|
||||
`(("marginnote" .
|
||||
(lambda (&rest args)
|
||||
(let ((note (string-join args "\\\n")))
|
||||
(concat
|
||||
"@@html:"
|
||||
(ox-tufte--utils-margin-note note)
|
||||
"@@")))))
|
||||
"Additional macros that are available during export.")
|
||||
|
||||
(defun ox-tufte--utils-margin-note (desc)
|
||||
"Return HTML snippet after interpreting DESC as a margin note.
|
||||
|
||||
This intended to be called via the `marginnote' library-of-babel function."
|
||||
(if org-tufte-feature-more-expressive-inline-marginnotes
|
||||
(let* ((ox-tufte--mn-macro-templates org-macro-templates)
|
||||
;; ^ copy buffer-local variable
|
||||
(exported-str
|
||||
(progn
|
||||
;; (save-excursion
|
||||
;; (message "HMM: desc = '%s'" desc)
|
||||
;; (message "HMM: buffer-string = '%s'" (buffer-string))
|
||||
;; (goto-char (point-min))
|
||||
;; (let ((end (search-forward desc))
|
||||
;; (beg (match-beginning 0)))
|
||||
;; (narrow-to-region beg end)
|
||||
;; (let ((output-buf (org-html-export-as-html nil nil
|
||||
;; nil t)))
|
||||
;; (widen)
|
||||
;; (with-current-buffer output-buf
|
||||
;; (buffer-string)))))
|
||||
(with-temp-buffer
|
||||
;; FIXME: use narrowing instead to obviate having to add functions
|
||||
;; to library-of-babel in `org-tufte-publish-to-html' etc.
|
||||
(insert desc)
|
||||
(let* ((org-export-global-macros ;; make buffer macros accessible
|
||||
(append ox-tufte--mn-macro-templates org-export-global-macros))
|
||||
;; nested footnotes aren't supported
|
||||
(org-html-footnotes-section "<!-- %s --><!-- %s -->")
|
||||
(output-buf (org-html-export-as-html nil nil nil t)))
|
||||
(with-current-buffer output-buf (buffer-string))))))
|
||||
(exported-newline-fix (replace-regexp-in-string
|
||||
"\n" " "
|
||||
(replace-regexp-in-string
|
||||
"\\\\\n" "<br>"
|
||||
exported-str)))
|
||||
(exported-para-fix (ox-tufte--utils-filter-ptags exported-newline-fix)))
|
||||
(ox-tufte--utils-margin-note-snippet exported-para-fix))
|
||||
""))
|
||||
|
||||
(defun ox-tufte--utils-margin-note-snippet (text &optional idtag blob)
|
||||
"Generate html snippet for margin-note with TEXT.
|
||||
|
||||
TEXT shouldn't have any <p> tags (or behaviour is undefined). If
|
||||
<p> tags are needed, use BLOB which must be an HTML snippet of a
|
||||
containing element with `marginnote' class. BLOB is ignored
|
||||
unless TEXT is nil.
|
||||
|
||||
IDTAG is used in the construction of the `id' that connects a
|
||||
margin-notes visibility-toggle with the margin-note."
|
||||
(let ((mnid (format "mn-%s.%s" (or idtag "auto") (ox-tufte--utils-randid)))
|
||||
(content (if text
|
||||
(format "<span class='marginnote'>%s</span>" text)
|
||||
blob)))
|
||||
(format
|
||||
(concat
|
||||
"<label for='%s' class='margin-toggle'>"
|
||||
org-tufte-margin-note-symbol
|
||||
"</label>"
|
||||
"<input type='checkbox' id='%s' class='margin-toggle'>"
|
||||
"%s")
|
||||
mnid mnid
|
||||
content)))
|
||||
|
||||
(defun ox-tufte--utils-string-fragment-to-xml (str)
|
||||
"Parse string fragment via `libxml'.
|
||||
STR is the xml fragment.
|
||||
|
||||
For the inverse, use something like `esxml-to-xml' (from package
|
||||
`esxml'). This function is presently never used (an intermediate
|
||||
version of `ox-tufte' used it)."
|
||||
(cl-assert (libxml-available-p))
|
||||
(with-temp-buffer
|
||||
(insert str)
|
||||
;; we really want to use `libxml-parse-xml-region', but that's too
|
||||
;; strict. `libxml-parse-html-region' is more lax (and that's good for us),
|
||||
;; but it creates <html> and <body> tags when missing. since we'll only be
|
||||
;; using this function on html fragments, we can assume these elements are
|
||||
;; always added and thus are safe to strip away
|
||||
(caddr ;; strip <body> tag
|
||||
(caddr ;; strip <html> tag
|
||||
(libxml-parse-html-region (point-min) (point-max))))))
|
||||
|
||||
(defun ox-tufte--utils-randid ()
|
||||
"Give a random number below the `org-tufte-randid-limit'."
|
||||
(random org-tufte-randid-limit))
|
||||
|
||||
|
||||
;;; Common customizations to ensure compatibility with both tufte-css and
|
||||
;;; ox-html
|
||||
|
||||
(defvar ox-tufte--sema-in-tufte-export nil
|
||||
"Currently in the midst of an export.")
|
||||
(defvar ox-tufte--store-confirm-babel-evaluate nil
|
||||
"Store value of `org-confirm-babel-evaluate'.")
|
||||
|
||||
(defun ox-tufte--utils-permit-mn-babel-call (lang body)
|
||||
"Permit evaluation of marginnote babel-call.
|
||||
LANG is the language of the code block whose text is BODY,"
|
||||
(if (and (string= lang "elisp")
|
||||
(string= body "(require 'ox-tufte)
|
||||
(ox-tufte--utils-margin-note input)"))
|
||||
nil
|
||||
ox-tufte--store-confirm-babel-evaluate))
|
||||
(defun ox-tufte--utils-entrypoint-funcall (filename function &rest args)
|
||||
"Call FUNCTION with ARGS in a \"normalized\" environment.
|
||||
FILENAME is intended to be the file being processed by one of the
|
||||
entrypoint function (e.g. `org-tufte-publish-to-html')."
|
||||
(let ((ox-tufte--store-confirm-babel-evaluate
|
||||
(if ox-tufte--sema-in-tufte-export
|
||||
ox-tufte--store-confirm-babel-evaluate
|
||||
org-confirm-babel-evaluate))
|
||||
(ox-tufte--sema-in-tufte-export t)
|
||||
(org-html-divs '((preamble "header" "preamble") ;; `header' i/o `div'
|
||||
(content "article" "content") ;; `article' for `tufte.css'
|
||||
(postamble "footer" "postamble")) ;; `footer' i/o `div'
|
||||
)
|
||||
(org-html-container-element "section") ;; consistent with `tufte.css'
|
||||
(org-html-checkbox-type 'html)
|
||||
(org-html-doctype "html5")
|
||||
(org-html-html5-fancy t)
|
||||
(org-confirm-babel-evaluate #'ox-tufte--utils-permit-mn-babel-call)
|
||||
(org-export-global-macros (append org-export-global-macros
|
||||
ox-tufte--utils-macros-alist))
|
||||
(ox-tufte/tmp/lob-pre org-babel-library-of-babel))
|
||||
;; FIXME: could this be obviated for mn-as-macro and mn-as-babelcall syntax?
|
||||
(when org-tufte-feature-more-expressive-inline-marginnotes
|
||||
(let ((inhibit-message t)) ;; silence lob ingestion messages
|
||||
(org-babel-lob-ingest filename))) ;; needed by `ox-tufte--utils-margin-note'
|
||||
(let ((output (apply function args)))
|
||||
(setq org-babel-library-of-babel ox-tufte/tmp/lob-pre)
|
||||
output)))
|
||||
|
||||
(defun ox-tufte--utils-get-export-output-extension (plist)
|
||||
"Get export filename extension based on PLIST."
|
||||
(concat
|
||||
(when (> (length org-html-extension) 0) ".")
|
||||
(or (plist-get plist :html-extension)
|
||||
org-html-extension
|
||||
"html")))
|
||||
|
||||
|
||||
;;; Transcode Functions
|
||||
|
||||
(defun org-tufte-quote-block (quote-block contents info)
|
||||
"Transform a quote block into an epigraph in Tufte HTML style.
|
||||
QUOTE-BLOCK CONTENTS INFO are as they are in `org-html-quote-block'."
|
||||
(let* ((ox-tufte/ox-html-qb-str (org-html-quote-block quote-block contents info))
|
||||
(ox-tufte/qb-caption (org-export-data
|
||||
(org-export-get-caption quote-block) info))
|
||||
(ox-tufte/footer-content-maybe
|
||||
(if (org-string-nw-p ox-tufte/qb-caption)
|
||||
(format "<footer>%s</footer>" ox-tufte/qb-caption)
|
||||
nil)))
|
||||
(if ox-tufte/footer-content-maybe
|
||||
(replace-regexp-in-string
|
||||
"</blockquote>\\'"
|
||||
(concat ox-tufte/footer-content-maybe "</blockquote>")
|
||||
ox-tufte/ox-html-qb-str t t)
|
||||
ox-tufte/ox-html-qb-str)))
|
||||
|
||||
(defun org-tufte-verse-block (verse-block contents info)
|
||||
"Transcode a VERSE-BLOCK element from Org to HTML.
|
||||
CONTENTS is verse block contents. INFO is a plist holding
|
||||
contextual information."
|
||||
(let* ((ox-tufte/ox-html-vb-str (org-html-verse-block verse-block contents info))
|
||||
(ox-tufte/vb-caption (org-export-data
|
||||
(org-export-get-caption verse-block) info))
|
||||
(ox-tufte/footer-content
|
||||
(if (org-string-nw-p ox-tufte/vb-caption)
|
||||
(format "<footer>%s</footer>" ox-tufte/vb-caption)
|
||||
"")))
|
||||
(format "<div class='verse'><blockquote>\n%s\n%s</blockquote></div>"
|
||||
ox-tufte/ox-html-vb-str
|
||||
ox-tufte/footer-content)))
|
||||
|
||||
(defun org-tufte-footnote-section-advice (fun &rest args)
|
||||
"Modify `org-html-footnote-section' based on `:footnotes-section-p'.
|
||||
FUN is `org-html-footnote-section' and ARGS is single-element
|
||||
list containing the plist (\"communication channel\")."
|
||||
(if ox-tufte--sema-in-tufte-export
|
||||
(let ((switch-p (plist-get (car args) :footnotes-section-p)))
|
||||
(if switch-p (apply fun args)
|
||||
""))
|
||||
(apply fun args)))
|
||||
(advice-add 'org-html-footnote-section
|
||||
:around #'org-tufte-footnote-section-advice)
|
||||
;; ox-html: definition: id="fn.<id>"; href="#fnr.<id>"
|
||||
(defun org-tufte-footnote-reference (footnote-reference _contents info)
|
||||
"Create a footnote according to the tufte css format.
|
||||
FOOTNOTE-REFERENCE is the org element, CONTENTS is nil. INFO is a
|
||||
plist holding contextual information.
|
||||
|
||||
Modified from `org-html-footnote-reference' in `org-html'."
|
||||
(concat
|
||||
;; Insert separator between two footnotes in a row.
|
||||
(let ((prev (org-export-get-previous-element footnote-reference info)))
|
||||
(when (eq (org-element-type prev) 'footnote-reference)
|
||||
(plist-get info :html-footnote-separator)))
|
||||
(let* ((ox-tufte/fn-num
|
||||
(org-export-get-footnote-number footnote-reference info))
|
||||
(ox-tufte/uid (ox-tufte--utils-randid))
|
||||
(ox-tufte/fn-inputid (format "fnr-in.%d.%s" ox-tufte/fn-num ox-tufte/uid))
|
||||
(ox-tufte/fn-labelid ;; first reference acts as back-reference
|
||||
(if (org-export-footnote-first-reference-p footnote-reference info)
|
||||
(format "fnr.%d" ox-tufte/fn-num) ;; this conforms to `ox-html.el'
|
||||
(format "fnr.%d.%s" ox-tufte/fn-num ox-tufte/uid)))
|
||||
(ox-tufte/fn-def
|
||||
(org-export-get-footnote-definition footnote-reference info))
|
||||
(ox-tufte/fn-data
|
||||
(org-trim (org-export-data ox-tufte/fn-def info)))
|
||||
(ox-tufte/fn-data-unpar
|
||||
;; footnotes must have spurious <p> tags removed or they will not work
|
||||
(ox-tufte--utils-filter-ptags ox-tufte/fn-data)))
|
||||
(format
|
||||
(concat
|
||||
"<label id='%s' for='%s' class='margin-toggle sidenote-number'><sup class='numeral'>%s</sup></label>"
|
||||
"<input type='checkbox' id='%s' class='margin-toggle'>"
|
||||
"<span class='sidenote'><sup class='numeral'>%s</sup>%s</span>")
|
||||
ox-tufte/fn-labelid ox-tufte/fn-inputid ox-tufte/fn-num
|
||||
ox-tufte/fn-inputid
|
||||
ox-tufte/fn-num ox-tufte/fn-data-unpar))))
|
||||
|
||||
(defun org-tufte-special-block (special-block contents info)
|
||||
"Add support for block margin-note special blocks.
|
||||
Pass SPECIAL-BLOCK CONTENTS and INFO to `org-html-special-block' otherwise."
|
||||
(let ((block-type (org-element-property :type special-block)))
|
||||
(cond
|
||||
((string= block-type "marginnote")
|
||||
(ox-tufte--utils-margin-note-snippet
|
||||
nil nil (org-html-special-block special-block contents info)))
|
||||
((and (string= block-type "figure")
|
||||
(org-html--has-caption-p special-block info)
|
||||
(not (member "iframe-wrapper" ;; FIXME: fix tufte-css before enabling
|
||||
(split-string
|
||||
(plist-get (org-export-read-attribute :attr_html special-block) :class)
|
||||
" "))))
|
||||
;; add support for captions on figures that `ox-html' lacks
|
||||
(let* ((caption (let ((raw (org-export-data
|
||||
(org-export-get-caption special-block) info)))
|
||||
(if (not (org-string-nw-p raw)) raw
|
||||
;; FIXME: it would be nice to be able to count figure
|
||||
;; as an image and number accordingly
|
||||
raw
|
||||
;; (concat "<span class=\"figure-number\">"
|
||||
;; (format (org-html--translate "Figure %d:" info)
|
||||
;; (org-export-get-ordinal
|
||||
;; (org-element-map special-block 'link
|
||||
;; #'identity info t)
|
||||
;; info '(link) #'org-html-standalone-image-p))
|
||||
;; " </span>"
|
||||
;; raw)
|
||||
)))
|
||||
(figcaption (format "<figcaption>%s</figcaption>" caption))
|
||||
;; using regex because `esxml-to-xml' doesn't put closing iframe
|
||||
;; tag (and also loses some attributes), which results in broken
|
||||
;; html (so cannot do what we do in `org-tufte-quote-block'.
|
||||
(o-h-sb-str (org-html-special-block special-block contents info)))
|
||||
(replace-regexp-in-string
|
||||
"</figure>\\'"
|
||||
(concat figcaption "</figure>") o-h-sb-str t t)))
|
||||
(t (org-html-special-block special-block contents info)))))
|
||||
|
||||
(defun org-tufte-maybe-margin-note-link (link desc info)
|
||||
"Render LINK as a margin note if it begins with `mn:'.
|
||||
For example, `[[mn:1][this is some text]]' is margin note 1 that
|
||||
will show \"this is some text\" in the margin.
|
||||
|
||||
If it does not, it will be passed onto the original function in
|
||||
order to be handled properly. DESC is the description part of the
|
||||
link. INFO is a plist holding contextual information.
|
||||
|
||||
Defining margin-note link in this manner, as opposed to via
|
||||
`org-link-set-parameters', ensures that margin-notes are only
|
||||
handled when occurring as regular links and not as angle or plain
|
||||
links. Additionally, it ensures that we only handle margin-notes
|
||||
for HTML backend without having an opinion on how to treat them
|
||||
for other backends."
|
||||
(let ((path (split-string (org-element-property :path link) ":"))
|
||||
(desc (or desc "")))
|
||||
(if (and (string= (org-element-property :type link) "fuzzy")
|
||||
(string= (car path) "mn"))
|
||||
(ox-tufte--utils-margin-note-snippet
|
||||
(ox-tufte--utils-filter-ptags desc)
|
||||
(if (string= (cadr path) "") nil (cadr path)))
|
||||
(org-html-link link desc info))))
|
||||
|
||||
(defun org-tufte-src-block (src-block _contents info)
|
||||
"Transcode SRC-BLOCK element into Tufte HTML format.
|
||||
CONTENTS is nil. INFO is a plist used as a communication channel.
|
||||
|
||||
NOTE: this is dead code and currently unused."
|
||||
(format "<pre class=\"code\"><code>%s</code></pre>"
|
||||
(org-html-format-code src-block info)))
|
||||
|
||||
|
||||
;;; Export functions
|
||||
|
||||
;;;###autoload
|
||||
(defun org-tufte-export-as-html
|
||||
(&optional async subtreep visible-only body-only ext-plist)
|
||||
"Export current buffer to a Tufte HTML buffer.
|
||||
|
||||
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 buffer 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.
|
||||
|
||||
Export is done in a buffer named \"*Org Tufte Export*\", which will
|
||||
be displayed when `org-export-show-temporary-export-buffer' is
|
||||
non-nil."
|
||||
(interactive)
|
||||
(ox-tufte--utils-entrypoint-funcall
|
||||
buffer-file-name
|
||||
#'org-export-to-buffer 'tufte-html "*Org Tufte Export*"
|
||||
async subtreep visible-only body-only ext-plist
|
||||
(lambda () (set-auto-mode t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-tufte-export-to-html
|
||||
(&optional async subtreep visible-only body-only ext-plist)
|
||||
"Export current buffer to a Tufte HTML file.
|
||||
|
||||
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 file 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 file's name."
|
||||
(interactive)
|
||||
(let ((file (org-export-output-file-name
|
||||
(ox-tufte--utils-get-export-output-extension ext-plist)
|
||||
subtreep)))
|
||||
(ox-tufte--utils-entrypoint-funcall
|
||||
buffer-file-name
|
||||
#'org-export-to-file 'tufte-html file
|
||||
async subtreep visible-only body-only ext-plist)))
|
||||
|
||||
|
||||
;;; publishing function
|
||||
|
||||
;;;###autoload
|
||||
(defun org-tufte-publish-to-html (plist filename pub-dir)
|
||||
"Publish an org file to Tufte-styled HTML.
|
||||
|
||||
PLIST is the property list for the given project. FILENAME is
|
||||
the filename of the Org file to be published. PUB-DIR is the
|
||||
publishing directory.
|
||||
|
||||
Return output file name."
|
||||
(ox-tufte--utils-entrypoint-funcall
|
||||
filename
|
||||
#'org-publish-org-to 'tufte-html filename
|
||||
(ox-tufte--utils-get-export-output-extension plist)
|
||||
plist pub-dir))
|
||||
|
||||
(provide 'ox-tufte)
|
||||
|
||||
;;; ox-tufte.el ends here
|
||||
345
lisp/ox-tufte/src/README.org
Normal file
345
lisp/ox-tufte/src/README.org
Normal file
@@ -0,0 +1,345 @@
|
||||
#+TITLE: Ox-tufte
|
||||
#+AUTHOR: The Bayesians Inc.
|
||||
|
||||
[[https://melpa.org/#/ox-tufte][file:https://melpa.org/packages/ox-tufte-badge.svg]]
|
||||
[[https://stable.melpa.org/#/ox-tufte][file:https://stable.melpa.org/packages/ox-tufte-badge.svg]]
|
||||
|
||||
* Changes since version 2.x
|
||||
- =ox-tufte-init= is no longer needed in addition to loading the library and has
|
||||
been removed.
|
||||
- inline margin-note syntax changes
|
||||
- inline margin-note-as-macro syntax has been added.
|
||||
- margin-note-as-link syntax has been un-deprecated.
|
||||
- all three inline margin-note syntaxes (=-as-babel-call=, =-as-macro=,
|
||||
=-as-link=) are documented with their respective limitations and quirks.
|
||||
* Introduction
|
||||
[[https://edwardtufte.github.io/tufte-css/][Tufte CSS]] has visually appealing defaults for webpages and supports (among other
|
||||
things) margin and side notes. Unfortunately, /Tufte CSS/ makes a number of
|
||||
demands of the HTML structure. This is a pity, because the HTML generated by
|
||||
=ox-html= breaks some of those assumptions (of =tufte-css=). Using =ox-tufte=
|
||||
you can avail the features of =tufte-css= when exporting an org-mode file to
|
||||
HTML. Since version 2+, the design goal of =ox-tufte= has been to *minimally*
|
||||
change the HTML structure generated by =ox-html= (with additional CSS as needed)
|
||||
to get behaviour that is equivalent to =tufte-css=.
|
||||
|
||||
=ox-tufte= tries very hard to not introduce additional constraints (over and
|
||||
above those imposed by =ox-html= and =tufte-css=) for users. In fact, work on
|
||||
=ox-tufte= [[https://github.com/ox-tufte/ox-tufte/milestone/1][version 2]] began after noticing that:
|
||||
- =ox-tufte= was broken and didn't faithfully reproduce the =tufte-css=
|
||||
experience.
|
||||
- [[https://github.com/Zilong-Li/org-tufte][org-tufte]] made additional assumptions and was too opinionated. E.g.,
|
||||
- deviations from =ox-html=
|
||||
- [[https://github.com/Zilong-Li/org-tufte/blob/404ab1286139ea6cbdc00bb1fb50a0afd9d067de/org-tufte.el#L102][use of katex instead of mathjax]]
|
||||
- [[https://github.com/Zilong-Li/org-tufte/blob/404ab1286139ea6cbdc00bb1fb50a0afd9d067de/org-tufte.el#L87][modified html-template]]
|
||||
- [[https://github.com/Zilong-Li/org-tufte/blob/404ab1286139ea6cbdc00bb1fb50a0afd9d067de/org-tufte.el#L97][automated inclusion of css hosted at third-party location]]
|
||||
|
||||
=ox-tufte= is still a work-in-progress, but it is being used by at least [[https://weary-travelers.gitlab.io/][one
|
||||
blog]] in "production". Please open an issue if you discover any bugs!
|
||||
** Compatibility
|
||||
Ox-tufte is compatible and tested with
|
||||
- =tufte-css= [[https://github.com/edwardtufte/tufte-css/releases/tag/v1.8.0][v1.8.0]]
|
||||
- =org-mode= >= 9.5
|
||||
- =emacs= >= 27.1
|
||||
|
||||
It's worth noting that Emacs 27.1 comes with Org version 9.3 (Org version 9.5
|
||||
comes with Emacs 28.1), however, it can be updated via Emacs's "package menu"
|
||||
(M-x list-packages).
|
||||
|
||||
Please open issues if you discover any incompatibility!
|
||||
* Installation and Usage
|
||||
You can install ox-tufte using [[https://melpa.org][MELPA]]:
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "http://melpa.org/packages/") t)
|
||||
|
||||
(package-refresh-contents)
|
||||
(package-install 'ox-tufte)
|
||||
#+END_SRC
|
||||
|
||||
And then in your ~init.el~ (or equivalent):
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(require 'ox-tufte)
|
||||
#+END_SRC
|
||||
|
||||
It's important that you download [[https://github.com/edwardtufte/tufte-css][tufte css]] ([[https://github.com/edwardtufte/tufte-css/releases/tag/v1.8.0][v1.8.0]]) and place it on your server
|
||||
(with the fonts).
|
||||
|
||||
** Usage
|
||||
The recommended way to use =ox-tufte= is *with* [[https://orgmode.org/manual/CSS-support.html][the default style provided by
|
||||
ox-html]]. Include =tufte.css= followed by =src/ox-tufte.css= (strictly in that
|
||||
order) in your org-mode document. This can be done by setting [[https://github.com/emacs-straight/org-mode/blob/ca873f7fe47546bca19821f1578a6ab95bf5351c/lisp/ox-html.el#L134][the =:html-head=
|
||||
option for ox-html]]. This can be done in elisp, or done in the specific
|
||||
org-mode document by adding a header such as:
|
||||
#+BEGIN_SRC org
|
||||
,#+HTML_HEAD: <link rel="stylesheet" href="/path/to/tufte.css" type="text/css" />
|
||||
,#+HTML_HEAD: <link rel="stylesheet" href="/path/to/ox-tufte.css" type="text/css" />
|
||||
#+END_SRC
|
||||
|
||||
For usage, when exporting simply select "Tufte HTML" instead of regular HTML
|
||||
export from the export menu (=C-c C-e=).
|
||||
* Features
|
||||
ox-tufte supports *most* of the features from tufte-css, some in different ways
|
||||
than expected, and some extensions.
|
||||
| [[https://edwardtufte.github.io/tufte-css/][Tufte-css concept]] | [[https://orgmode.org/worg/org-syntax.html][Org-mode syntax]] for tufte-css concept | ox-tufte extension |
|
||||
|-----------------------+-------------------------------------------------+---------------------------------------------------|
|
||||
| [[https://edwardtufte.github.io/tufte-css/#fundamentals--sections-and-headers][Sections and Headings]] | Sections and Headings | |
|
||||
| [[https://edwardtufte.github.io/tufte-css/#sidenotes][Sidenotes]] | [[footnotes][Footnotes]] | |
|
||||
| [[https://edwardtufte.github.io/tufte-css/#sidenotes][Margin-notes]] | [[marginnotes-inline][inline babel call]] to [[marginnote]["marginnote" block]] | block margin-notes via "marginnote" special-block |
|
||||
| [[https://edwardtufte.github.io/tufte-css/#epigraphs][Epigraphs]] | [[epigraphs][Quote block]] | |
|
||||
| [[https://edwardtufte.github.io/tufte-css/#figures][iframe wrapper]] | [[figures]["figure"]] org-mode [[https://orgmode.org/org.html#HTML-doctypes][special-block]] | |
|
||||
| [[https://edwardtufte.github.io/tufte-css/#code][Code]] | [[code][Source block]] | |
|
||||
| [[https://edwardtufte.github.io/tufte-css/#imagequilts][ImageQuilts]] | [[quilts][single image or images in"figure" special-block]] | |
|
||||
|
||||
** [[https://edwardtufte.github.io/tufte-css/#sidenotes][Sidenotes and margin-notes]]
|
||||
<<footnotes>>Org-mode footnotes become numbered Sidenotes from the tufte
|
||||
spec. The only limitation (inherited from =tufte-css=) is that a footnote can no
|
||||
longer include another footnote within.
|
||||
*** Inline margin-notes
|
||||
<<marginnotes-inline>>Since, Org-mode doesn't yet support syntax for inline
|
||||
special blocks ([[https://list.orgmode.org/orgmode/87a6b8pbhg.fsf@posteo.net/][though it's being discussed and may be implemented in the near
|
||||
future]]), there are multiple ways to express inline margin-notes (i.e.,
|
||||
margin-notes that can include [[https://html.spec.whatwg.org/#phrasing-content-2][HTML phrasing content]]). Inline margin-notes are
|
||||
implemented in their most feature-full incarnation as an inline babel call,
|
||||
specifically, to [[marginnote][the "marginnote" block defined below]].
|
||||
#+name: marginnote
|
||||
#+header: :var input=""
|
||||
#+begin_src elisp :eval yes :exports results :results html replace value
|
||||
(require 'ox-tufte)
|
||||
(ox-tufte--utils-margin-note input)
|
||||
#+end_src
|
||||
If the only content of an inline margin-note is a link to an image, the
|
||||
generated HTML will be malformed. Use the [[https://orgmode.org/manual/Escape-Character.html][zero width space escape character]] to
|
||||
communicate to the export process that the rendered image is to be contained
|
||||
within a paragraph. If you need to enforce a line break within the margin-note,
|
||||
use =\\= at the end of a line as follows:
|
||||
#+begin_src org
|
||||
This is some regular text call_marginnote("this will be a margin note") and some
|
||||
more text call_marginnote("another margin note.\\
|
||||
new line in second margin note.").
|
||||
#+end_src
|
||||
An alternative syntax of an inline margin-note as a macro is also provided with
|
||||
the following additional (wrt the inline babel call syntax) caveats:
|
||||
- macro invocations are not permitted in this syntax
|
||||
- commas need to be escaped with a backslash (=\=)
|
||||
- line breaks can be enforced by adding an unescaped comma
|
||||
#+begin_src org
|
||||
This is some regular text {{{marginnote(this will be a margin note)}}} and some
|
||||
more text {{{marginnote(another margin note.,new line in second margin
|
||||
note.)}}}.
|
||||
#+end_src
|
||||
If, however, you only need an inline margin-note with some text without
|
||||
requiring specific control over line breaks or insertion of links or images (but
|
||||
still allowing for macro and babel call invocation), the margin-note-as-a-link
|
||||
syntax might be preferable.
|
||||
- The margin note number is optional and either `mn:1` or `mn:` as below would
|
||||
work:
|
||||
#+BEGIN_SRC org
|
||||
This is some regular text [[mn:1][this will be a margin note. while links aren't
|
||||
supported, commas don't need escaping.]] and some more text [[mn:][another margin note]].
|
||||
#+END_SRC
|
||||
The reason for not being able to insert links (or images) using this syntax is
|
||||
an org syntax limitation.
|
||||
*** Block margin-notes
|
||||
There is also support for "block" margin-notes, which are margin-notes that can
|
||||
contain "block" elements ([[https://html.spec.whatwg.org/#flow-content-2][HTML spec flow content]]) such as paragraphs, lists,
|
||||
tables etc. These are defined using an org-mode "marginnote" special-block
|
||||
(i.e., within =#+begin_marginnote= and =#+end_marginnote=, or within
|
||||
=#+BEGIN_marginnote= and =#+END_marginnote=).
|
||||
#+begin_src org
|
||||
,#+begin_marginnote
|
||||
This is a block level margin-note.
|
||||
- item 1
|
||||
- item 2
|
||||
,#+end_marginnote
|
||||
#+end_src
|
||||
The block marginnote is displayed to the right side of the paragraph following
|
||||
it. In case a block margin-note is needed in [[https://orgmode.org/worg/org-syntax.html#Zeroth_section][the zeroth section]] (i.e., before
|
||||
the first heading in an org document), it needs to be wrapped within
|
||||
=#+begin_zeroth-section= and =#+end_zeroth-section= as follows:
|
||||
#+begin_src org
|
||||
,#+begin_zeroth-section
|
||||
,#+begin_marginnote
|
||||
This is a block level margin-note.
|
||||
- item 1
|
||||
- item 2
|
||||
,#+end_marginnote
|
||||
,#+end_zeroth-section
|
||||
#+end_src
|
||||
|
||||
** <<epigraphs>>[[https://edwardtufte.github.io/tufte-css/#epigraphs][Epigraphs]] and [[https://orgmode.org/manual/Paragraphs.html#index-BEGIN_005fVERSE][quotes]]
|
||||
- Anything within =#+begin_epigraph= and =#+end_epigraph= becomes an epigraph
|
||||
(which is a collection of one or more quoted blocks). For example:
|
||||
#+begin_src org
|
||||
,#+begin_epigraph
|
||||
,#+name: quote-1
|
||||
,#+caption: Richard P. Feynman, @@html:<cite>“What Do You Care What Other People Think?”</cite>@@
|
||||
,#+begin_quote
|
||||
For a successful technology, reality must take precedence over public relations,
|
||||
for Nature cannot be fooled.
|
||||
,#+end_quote
|
||||
|
||||
,#+name: quote-2
|
||||
,#+caption: Henri Matisse, @@html:<cite>Henri Matisse Dessins: thèmes et variations</cite>@@ (Paris, 1943), 37
|
||||
,#+begin_quote
|
||||
I do not paint things, I paint only the differences between things.
|
||||
,#+end_quote
|
||||
,#+end_epigraph
|
||||
#+end_src
|
||||
- =ox-tufte= also adds support for =#+CAPTION= on [[https://orgmode.org/manual/Paragraphs.html#index-BEGIN_005fVERSE][org-mode =quote= and =verse= blocks]].
|
||||
** <<code>>[[https://edwardtufte.github.io/tufte-css/#code][Code]]
|
||||
=ox-tufte= uses =ox-html= to export [[https://orgmode.org/manual/Literal-Examples.html][code fragments]] to HTML (without any
|
||||
alteration). =ox-html= and [[https://elpa.nongnu.org/nongnu/htmlize.html][=htmlize=]] allow one to customize the syntax
|
||||
highlighting of the exported code blocks. An Emacs color theme that is visually
|
||||
consistent with =tufte-css= is the [[https://melpa.org/#/plan9-theme][=plan9-theme=]] which can be installed from
|
||||
Melpa via something like:
|
||||
#+begin_src elisp
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "http://melpa.org/packages/") t)
|
||||
|
||||
(package-refresh-contents)
|
||||
(package-install 'plan9-theme)
|
||||
#+end_src
|
||||
And then in your =init.el= or equivalent, load it using:
|
||||
src_elisp{(load-theme 'plan9 t)}.
|
||||
** <<figures>>Figures and iframes
|
||||
To use =tufte-css='s =iframe-wrapper= class, one can do something like below:
|
||||
#+begin_src org
|
||||
,#+ATTR_HTML: :class iframe-wrapper
|
||||
,#+begin_figure
|
||||
@@html:<iframe width="853" height="480" src="https://www.youtube.com/embed/YslQ2625TR4" frameborder="0" allowfullscreen></iframe>@@
|
||||
,#+end_figure
|
||||
#+end_src
|
||||
|
||||
To have fullwidth figures:
|
||||
#+begin_src org
|
||||
,#+ATTR_HTML: :class fullwidth
|
||||
,#+begin_figure
|
||||
,#+CAPTION: Edward Tufte’s English translation of the Napoleon’s March data visualization. From Beautiful Evidence, page 122-124.
|
||||
[[https://edwardtufte.github.io/tufte-css/img/napoleons-march.png]]
|
||||
,#+end_figure
|
||||
#+end_src
|
||||
Alternatively, the =fullwidth= class can also be applied to the image
|
||||
directly. However, in this case the resulting image may not truly be
|
||||
"fullwidth".
|
||||
#+begin_src org
|
||||
,#+ATTR_HTML: :class fullwidth
|
||||
,#+CAPTION: Edward Tufte’s English translation of the Napoleon’s March data visualization. From Beautiful Evidence, page 122-124.
|
||||
[[https://edwardtufte.github.io/tufte-css/img/napoleons-march.png]]
|
||||
#+end_src
|
||||
Experiment and choose depending on your application.
|
||||
** <<quilts>>ImageQuilts
|
||||
=tufte-css= has a notion of image quilts. [[https://edwardtufte.github.io/tufte-css/#imagequilts][the examples on tufte-css website]] are
|
||||
single images that were created by combining multiple images. However, that
|
||||
processing was done before linking via html. It's unclear what, if any,
|
||||
conveniences =tufte-css= provides for image quilts (over and above other
|
||||
features, since [[figures][single images can already be included as desired]]).
|
||||
|
||||
However, in =ox-tufte= one can create a figure with multiple images.
|
||||
#+begin_src org
|
||||
,#+HTML_HEAD_EXTRA: <style> .quiltish img { max-height: 200px; min-height: 100px; } </style>
|
||||
,#+attr_html: :class quiltish
|
||||
,#+CAPTION: caption for multiple images
|
||||
,#+begin_figure
|
||||
[[./path/to/img1.png]]
|
||||
[[./path/to/img2.png]]
|
||||
,#+end_figure
|
||||
#+end_src
|
||||
** Deviations and Extensions (from =tufte-css= and =ox-html=)
|
||||
*** Sections and Headings
|
||||
- =h4= heading level is supported in a consistent manner similar to =h3=.
|
||||
*** Epigraphs
|
||||
Epigraphs and quotes by default occupy only the width of the main content. In
|
||||
order to get quoted content that extends for the fullwidth add the =fullwidth=
|
||||
class with an =#+attr_html= annotation.
|
||||
*** Sidenotes and margin-notes
|
||||
- =tufte-css= numbers sidenotes via CSS and as such referring to the same
|
||||
sidenote more than once results in erroneous numbering. =ox-tufte= fixes
|
||||
this.
|
||||
- Block margin-notes are supported via src_org{#+begin_marginnote} and
|
||||
src_org{#+end_marginnote}.
|
||||
*** Figures
|
||||
- Captions on images are placed below the image (as opposed to in the margin
|
||||
area) regardless of whether the image is =fullwidth= or not.
|
||||
*** Code
|
||||
- Since code blocks cannot have footnotes/sidenotes in them, they are treated as
|
||||
if they were using the "fullwidth" class (without having to specify the class
|
||||
via =#+attr_html=).
|
||||
*** ImageQuilts
|
||||
- Unlike =ox-html=, in =ox-tufte= captions on figure special-blocks (the kind
|
||||
used when including multiple images in a block, as in ImageQuilts) are
|
||||
included as figcaptions. *Limitation:* presently the included caption doesn't
|
||||
include automated numbering.
|
||||
** Experimental
|
||||
There may be some experimental extensions in =src/ox-tufte-experimental.css=.
|
||||
If desired, this css file should be included /after/ =src/ox-tufte.css=.
|
||||
* Limitations
|
||||
- The generated HTML is not compatible with [[https://orgmode.org/worg/code/org-info-js/][org-info.js]]. This is because
|
||||
=ox-tufte= customizes the value of =org-html-divs= to align it with what's
|
||||
expected by =tufte-css=.
|
||||
- Code blocks (multiline) currently behave /only/ in a "fullwidth" manner. I.e.,
|
||||
if there is sidenote content from previous paragraph, or a block margin-note
|
||||
it will push the code block down.
|
||||
|
||||
Additionally, =ox-tufte= presently inherits the following limitations from
|
||||
[[https://edwardtufte.github.io/tufte-css/][tufte-css]]:
|
||||
- Footnotes/sidenotes cannot contain nested footnotes/sidenotes.
|
||||
- Sidenotes cannot contain paragraphs, tables etc. (since they are HTML =span=
|
||||
elements).
|
||||
- Captions for =iframe-wrapper= blocks aren't supported.
|
||||
- The generated HTML must (and does) use an =html5= doctype.
|
||||
* Customization
|
||||
** Footnotes section at bottom
|
||||
The behaviour depends on the =:footnotes-section-p= option (which uses the value
|
||||
of ~org-tufte-include-footnotes-at-bottom~ as default).
|
||||
|
||||
Because footnotes are transformed to sidenotes they are currently hidden on very
|
||||
narrow screens (like phones), unless the use manually toggles visibility for
|
||||
each reference. if you want to include footnotes *also* at the bottom of the
|
||||
page, this may be set to =t= using =setq=:
|
||||
#+begin_src elisp
|
||||
(require 'ox-tufte)
|
||||
(setq org-tufte-include-footnotes-at-bottom t)
|
||||
#+end_src
|
||||
Or, if you're using =use-package=:
|
||||
#+begin_src elisp
|
||||
(use-package ox-tufte
|
||||
:config
|
||||
(setq org-tufte-include-footnotes-at-bottom t))
|
||||
#+end_src
|
||||
|
||||
This behaviour can also be configured on a per-file basis using:
|
||||
#+begin_src org
|
||||
,#+OPTIONS: footnotes-section-p:t
|
||||
#+end_src
|
||||
Or, (assuming =org-export-allow-bind-keywords= is =t=) using below:
|
||||
#+begin_src org
|
||||
,#+BIND: org-tufte-include-footnotes-at-bottom t
|
||||
#+end_src
|
||||
** Margin-note symbol and visibility on small screens
|
||||
From [[https://edwardtufte.github.io/tufte-css/][tufte-css]]:
|
||||
#+begin_quote
|
||||
However, on small screens, a margin note is like a sidenote except its
|
||||
viewability-toggle is a symbol rather than a reference number. This document
|
||||
currently uses the symbol ⊕ (⊕), but it’s up to you.
|
||||
#+end_quote
|
||||
This symbol can be tweaked, by modifying the value of
|
||||
=org-tufte-margin-note-symbol=. Specifically, if this value is set to the empty
|
||||
string (=""=), then margin-notes are always hidden on small screens.
|
||||
** Color of margin-note visibility-toggle and footnote-references
|
||||
Margin-note visibility color toggle can be tweaked using something like
|
||||
#+begin_src css
|
||||
label.margin-toggle {
|
||||
color: #a00000;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
For footnote references, something like below would work
|
||||
#+begin_src css
|
||||
label.sidenote-number,
|
||||
.sidenote > sup.numeral {
|
||||
color: #a00000;
|
||||
}
|
||||
#+end_src
|
||||
* References
|
||||
- https://edwardtufte.github.io/tufte-css/
|
||||
- https://gitlab.com/snippets/22309
|
||||
18
lisp/ox-tufte/src/ox-tufte-experimental.css
Normal file
18
lisp/ox-tufte/src/ox-tufte-experimental.css
Normal file
@@ -0,0 +1,18 @@
|
||||
/* NOTE: to be included in page after ox-tufte.css */
|
||||
|
||||
/**********************************************************/
|
||||
/* tufte.css consistent (somewhat opinionated) extensions */
|
||||
/**********************************************************/
|
||||
:root {
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
/* lists in sidenotes - breaks html standard and works only in special situations */
|
||||
/**********************************************************************************/
|
||||
.sidenote dl,
|
||||
.sidenote ol,
|
||||
.sidenote ul {
|
||||
font-size: var(--ox-tufte-note-font-size);
|
||||
line-height: var(--ox-tufte-note-line-height);
|
||||
}
|
||||
467
lisp/ox-tufte/src/ox-tufte.css
Normal file
467
lisp/ox-tufte/src/ox-tufte.css
Normal file
@@ -0,0 +1,467 @@
|
||||
:root {
|
||||
--ox-tufte-content-width: 55%; /* set value consistent with "section > p" */
|
||||
--ox-tufte-fullwidth: 163.636%; /* 90% of body, when ancestor is at 55% */
|
||||
--ox-tufte-src-code-width: 97%;
|
||||
/* 50+5=55% this is what is used by section > {dl, ol, ul} */
|
||||
--ox-tufte-list-width: 50%;
|
||||
--ox-tufte-list-padding-left: 5%;
|
||||
/* font-size and line-height settings from tufte.css */
|
||||
--ox-tufte-content-font-size: 1.4rem;
|
||||
--ox-tufte-content-line-height: 2rem;
|
||||
--ox-tufte-content-epigraph-margin-vertical: calc(5em / 1.4);
|
||||
/* ^ equivalent of 5em when element has 1rem font-size */
|
||||
--ox-tufte-note-line-height: 1.3;
|
||||
--ox-tufte-note-font-size: 1.1rem;
|
||||
--ox-tufte-note-code-font-size: 1rem;
|
||||
--ox-tufte-code-font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
--ox-tufte-code-font-size: 1.0rem;
|
||||
--ox-tufte-code-font-size-sans: 1.2rem; /* from ".sans > code" */
|
||||
--ox-tufte-code-line-height: 1.42;
|
||||
/* values tufte.css reuses for h1,h3,h3 */
|
||||
--ox-tufte-heading-font-style: italic;
|
||||
--ox-tufte-heading-font-weight: 400;
|
||||
--ox-tufte-heading-line-height: 1;
|
||||
--ox-tufte-heading-code-font-size: 0.80em;
|
||||
--ox-tufte-heading-min-margin-bottom: 1.4rem; /* h3=1.4rem; p=1.4rem; */
|
||||
--ox-tufte-heading-min-font-size: 1.4rem; /* p=1.4rem; */
|
||||
}
|
||||
|
||||
/* 1. Prevent adjustments of font size after orientation changes in iOS. */
|
||||
/* <https://github.com/necolas/normalize.css/blob/fc091cce1534909334c1911709a39c22d406977b/normalize.css#L13> */
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%; /* 1 */
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* re-specify tufte.css values, for compatibility with org-generated html */
|
||||
/**************************************************************************/
|
||||
article { /* add missing default from tufte.css */
|
||||
font-size: var(--ox-tufte-content-font-size);
|
||||
line-height: var(--ox-tufte-content-line-height);
|
||||
}
|
||||
article > p,
|
||||
article > div.epigraph,
|
||||
article > table,
|
||||
article > mjx-container,
|
||||
article > div.zeroth-section,
|
||||
section > div,
|
||||
section > h2 { /* set value consistent with "section > p" */
|
||||
width: var(--ox-tufte-content-width);
|
||||
}
|
||||
article > object {
|
||||
max-width: var(--ox-tufte-content-width);
|
||||
}
|
||||
article figure object {
|
||||
max-width: 100%;
|
||||
}
|
||||
article > p .fullwidth,
|
||||
article > div .fullwidth,
|
||||
section > div .fullwidth {
|
||||
max-width: var(--ox-tufte-fullwidth);
|
||||
width: max-content;
|
||||
}
|
||||
article > blockquote.fullwidth {
|
||||
width: max-content;
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
div.epigraph > blockquote.fullwidth {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
section > dl, section > ol, section > ul,
|
||||
article > dl, article > ol, article > ul {
|
||||
width: var(--ox-tufte-list-width);
|
||||
/* instead of tufte.css's -webkit-padding-start, which doesn't work */
|
||||
padding-inline-start: var(--ox-tufte-list-padding-left);
|
||||
}
|
||||
blockquote .marginnote, blockquote .sidenote {
|
||||
font-style: normal;
|
||||
}
|
||||
/* code blocks. tufte.css also allows for code within headers and
|
||||
* sidenotes/marginnotes. these are currently not supported by us. */
|
||||
.org-src-container {
|
||||
max-width: var(--ox-tufte-fullwidth);
|
||||
width: var(--ox-tufte-fullwidth);
|
||||
clear: both; /* necessary to prevent overlap between long label and sidenote */
|
||||
}
|
||||
body pre { /* monospace content: .src .example */
|
||||
/* FROM: pre.fullwidth > code in tufte.css; but adjusted */
|
||||
width: var(--ox-tufte-src-code-width);
|
||||
clear: both; /* ensure that it doesn't overlap sidenotes */
|
||||
/* unset some unnecessary 'org' defaults, which interfere with tufte */
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
}
|
||||
pre, code {
|
||||
/* FROM: "code, pre > code" in tufte.css */
|
||||
font-family: var(--ox-tufte-code-font-family);
|
||||
font-size: var(--ox-tufte-code-font-size);
|
||||
line-height: var(--ox-tufte-code-line-height);
|
||||
}
|
||||
.sans pre, .sans code {
|
||||
font-size: var(--ox-tufte-code-font-size-sans);
|
||||
line-height: var(--ox-tufte-code-line-height);
|
||||
}
|
||||
.sans h1 code, .sans h2 code, .sans h3 code,
|
||||
h1 code, h2 code, h3 code { /* fix for tufte.css */
|
||||
font-size: var(--ox-tufte-heading-code-font-size);
|
||||
}
|
||||
code {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.sidenote code, .marginnote code, /* inline code */
|
||||
.marginnote pre { /* code blocks */
|
||||
font-size: var(--ox-tufte-note-code-font-size);
|
||||
line-height: var(--ox-tufte-note-line-height);
|
||||
}
|
||||
|
||||
article div figure {
|
||||
/* tufte.css doesn't intend figure to be within div, but org generates it as
|
||||
* such. reset width to full width of article as tufte.css intends */
|
||||
max-width: 100%
|
||||
}
|
||||
blockquote p, blockquote footer {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
/* tufte.css fixes; should probably be submitted upstream */
|
||||
/**********************************************************/
|
||||
.sans .numeral { /* don't use et-book-roman-old-style when using .sans */
|
||||
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
|
||||
}
|
||||
article { /* needed, if sidenotes have large content */
|
||||
/* we don't apply this on "section", because we do want the sections to be
|
||||
* overlappable with the sidenotes of previous section */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* unset/alter org defaults */
|
||||
/****************************/
|
||||
#content { /* ID corresponding to main article (excluding pre/postamble) */
|
||||
max-width: 100%;
|
||||
}
|
||||
/* verse */
|
||||
p.verse { /* this verse element will always be within a <blockquote> */
|
||||
/* tufte.css already provides margin-left/right for enclosing blockquote */
|
||||
margin-left: 0;
|
||||
}
|
||||
#footnotes { /* needed, if sidenotes have large content */
|
||||
/* we want to make sure that the footnotes section starts after all the content
|
||||
* for "sections" and "sidenotes" is done */
|
||||
clear: both;
|
||||
width: unset;
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/* undo tufte.css defaults */
|
||||
/***************************/
|
||||
body pre.example { /* in org, this is within blockquote */
|
||||
font-style: normal;
|
||||
}
|
||||
/* verse: undoing "blockquote p, blockquote footer" from tufte.css */
|
||||
div.verse blockquote p, div.verse blockquote footer {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
/* verse blocks: support and distinguish from epigraphs */
|
||||
/********************************************************/
|
||||
div.verse > blockquote {
|
||||
/* gray bar on the left */
|
||||
border-left: 3px solid #ccc;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
/* tufte.css consistent extensions */
|
||||
/***********************************/
|
||||
/***************************/
|
||||
/* support for h4 headings */
|
||||
/***************************/
|
||||
h4 > code {
|
||||
font-size: var(--ox-tufte-heading-code-font-size);
|
||||
}
|
||||
h4 {
|
||||
font-style: var(--ox-tufte-heading-font-style);
|
||||
font-weight: var(--ox-tufte-heading-font-weight);
|
||||
margin-bottom: var(--ox-tufte-heading-min-margin-bottom);
|
||||
line-height: var(--ox-tufte-heading-line-height);
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.5rem; /* h3=1.7rem; */
|
||||
margin-top: 1.8rem; /* h3=2rem; */
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/* sidenotes in headings h2, h3, h4 */
|
||||
/************************************/
|
||||
h2 .sidenote, h2 .marginnote,
|
||||
h3 .sidenote, h3 .marginnote,
|
||||
h4 .sidenote, h4 .marginnote {
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* footnote reference */
|
||||
/**********************/
|
||||
.sidenote-number > sup.numeral, .sidenote > sup.numeral {
|
||||
/* same as ".sidenote-number:after", ".sidenote:before" */
|
||||
font-size: 1rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
/* we don't rely on CSS numbering */
|
||||
.sidenote-number:after, .sidenote:before {
|
||||
content: none;
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* small screen */
|
||||
/****************/
|
||||
@media (max-width: 760px) {
|
||||
:root {
|
||||
--ox-tufte-content-width: 100%;
|
||||
--ox-tufte-fullwidth: 100%;
|
||||
--ox-tufte-list-width: 90;
|
||||
--ox-tufte-list-padding-left: 10%;
|
||||
}
|
||||
/**********************************************************/
|
||||
/* tufte.css fixes; should probably be submitted upstream */
|
||||
/**********************************************************/
|
||||
.margin-toggle:checked + .sidenote,
|
||||
.margin-toggle:checked + .marginnote {
|
||||
/* what tufte.css does results in minute horizontal scrolling on*/
|
||||
/* sufficiently small screens; below fixes that */
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
left: 0;
|
||||
float: right;
|
||||
}
|
||||
.marginnote img, .sidenote img {
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* assorted bugfixes and additional tweaks */
|
||||
/* NOTE: code below likely needs to be refactored and assimilated into above */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* BEGIN: width and placement of sidenotes + lists, epigraphs */
|
||||
:root {
|
||||
--ox-tufte-sidenote-width-max: 385px;
|
||||
--ox-tufte-sidenote-width-standard: 50%;
|
||||
--ox-tufte-sidenote-margin-right-min: -462px;
|
||||
--ox-tufte-sidenote-margin-right-standard: -60%;
|
||||
}
|
||||
article > blockquote { /* assuming within an element 55% in width */
|
||||
width: 50%;
|
||||
margin-left: 5%;
|
||||
}
|
||||
blockquote {
|
||||
margin-left: calc(100% / 11);
|
||||
margin-right: 0;
|
||||
}
|
||||
blockquote .sidenote, blockquote .marginnote {
|
||||
min-width: unset;
|
||||
width:calc(var(--ox-tufte-sidenote-width-standard) / (10 / 11));
|
||||
margin-right:calc(var(--ox-tufte-sidenote-margin-right-standard) / (10 / 11));
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
div.epigraph blockquote p { overflow-y: auto; }
|
||||
}
|
||||
article ul, article ol, article dl {
|
||||
width: var(--ox-tufte-list-width); /* 50% */
|
||||
padding-inline-start: var(--ox-tufte-list-padding-left); /* 5% */
|
||||
}
|
||||
article ul ul, article ol ol, article ul ol, article ol ul {
|
||||
padding-inline-start: calc(100% / 10); /* 5% wrt body, when 100% is 50% */
|
||||
width: calc(100% * 9 / 10); /* 45% wrt body, when 100% is 50% */
|
||||
}
|
||||
article ul ul ul, article ol ol ul, article ul ol ul, article ol ul ul,
|
||||
article ul ul ol, article ol ol ol, article ul ol ol, article ol ul ol {
|
||||
padding-inline-start: calc(100% / 9); /* 5% wrt body, when 100% is 45% */
|
||||
width: calc(100% * 8 / 9); /* 40% wrt body, when 100% is 45% */
|
||||
}
|
||||
section ul, section ol, section dl {
|
||||
padding-inline-start: calc(100% / 11);
|
||||
width: calc(100% * 10 / 11);
|
||||
}
|
||||
article ul .sidenote, article ol .sidenote,
|
||||
article ul .marginnote, article ol .marginnote {
|
||||
width: min(var(--ox-tufte-sidenote-width-max), calc(var(--ox-tufte-sidenote-width-standard) / (10 / 11)));
|
||||
margin-right: max(var(--ox-tufte-sidenote-margin-right-min), calc(var(--ox-tufte-sidenote-margin-right-standard) / (10 / 11)));
|
||||
}
|
||||
article ul ul .sidenote, article ul ul .marginnote,
|
||||
article ul ol .sidenote, article ul ol .marginnote,
|
||||
article ol ol .sidenote, article ol ol .marginnote,
|
||||
article ol ul .sidenote, article ol ul .marginnote { /* 11/9 = 11/10 X(10/9) */
|
||||
width: min(var(--ox-tufte-sidenote-width-max), calc(var(--ox-tufte-sidenote-width-standard) / (9 / 11)));
|
||||
margin-right: max(var(--ox-tufte-sidenote-margin-right-min), calc(var(--ox-tufte-sidenote-margin-right-standard) / (9 / 11)));
|
||||
}
|
||||
article ul ul ul .sidenote, article ul ul ul .marginnote,
|
||||
article ul ul ol .sidenote, article ul ul ol .marginnote,
|
||||
article ul ol ul .sidenote, article ul ol ul .marginnote,
|
||||
article ul ol ol .sidenote, article ul ol ol .marginnote,
|
||||
article ol ol ul .sidenote, article ol ol ul .marginnote,
|
||||
article ol ol ol .sidenote, article ol ol ol .marginnote,
|
||||
article ol ul ul .sidenote, article ol ul ul .marginnote
|
||||
article ol ul ol .sidenote, article ol ul ol .marginnote { /* 11/8 = 11/10 X(10/9) X(9/8) */
|
||||
width: min(var(--ox-tufte-sidenote-width-max), calc(var(--ox-tufte-sidenote-width-standard) / (8 / 11)));
|
||||
margin-right: max(var(--ox-tufte-sidenote-margin-right-min), calc(var(--ox-tufte-sidenote-margin-right-standard) / (8 / 11)));
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
ul li, ol li {
|
||||
overflow-y: auto;
|
||||
/* however, this causes issues: https://stackoverflow.com/a/40912185 */
|
||||
list-style-position: inside;
|
||||
margin-left: -1em;
|
||||
}
|
||||
}
|
||||
/* fix padding issues first and make them percentages */
|
||||
article dl > dd {
|
||||
margin-left: calc(100% / 10);
|
||||
}
|
||||
/* fix sidenote width and margin-right */
|
||||
article dl dt .sidenote, article dl dt .marginnote {
|
||||
width: min(var(--ox-tufte-sidenote-width-max), calc(var(--ox-tufte-sidenote-width-standard) / (10 / 11)));
|
||||
margin-right: max(var(--ox-tufte-sidenote-margin-right-min), calc(var(--ox-tufte-sidenote-margin-right-standard) / (10 / 11)));
|
||||
font-weight: normal;
|
||||
}
|
||||
article dl dd .sidenote, article dl dd .marginnote { /* 11/9 = 11/10 X(10/9) */
|
||||
width: min(var(--ox-tufte-sidenote-width-max), calc(var(--ox-tufte-sidenote-width-standard) / (9 / 11)));
|
||||
margin-right: max(var(--ox-tufte-sidenote-margin-right-min), calc(var(--ox-tufte-sidenote-margin-right-standard) / (9 / 11)));
|
||||
}
|
||||
/* also check on smaller screens */
|
||||
@media (max-width: 760px) {
|
||||
dl dt, dl dd {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
article dl dl {
|
||||
padding-inline-start: calc(100% / 9); /* 5% wrt body, when 100% is 45% wrt body */
|
||||
width: calc(100% * 8 / 9); /* 40% wrt body */
|
||||
}
|
||||
article dl dl > dd {
|
||||
margin-left: calc(100% / 8) /* 5% wrt body, when 100% is 40% wrt body */
|
||||
}
|
||||
article dl dl dt .sidenote, article dl dl dt .marginnote { /* 11/8 = 11/10 x 10/9 x 9/8 */
|
||||
width: min(var(--ox-tufte-sidenote-width-max), calc(var(--ox-tufte-sidenote-width-standard) / (8 / 11)));
|
||||
margin-right: max(var(--ox-tufte-sidenote-margin-right-min), calc(var(--ox-tufte-sidenote-margin-right-standard) / (8 / 11)));
|
||||
font-weight: normal;
|
||||
}
|
||||
article dl dl dd .sidenote, article dl dl dd .marginnote { /* 11/7 */
|
||||
width: min(var(--ox-tufte-sidenote-width-max), calc(var(--ox-tufte-sidenote-width-standard) / (7 / 11)));
|
||||
margin-right: max(var(--ox-tufte-sidenote-margin-right-min), calc(var(--ox-tufte-sidenote-margin-right-standard) / (7 / 11)));
|
||||
}
|
||||
|
||||
/* BEGIN BONUS: fix top-level code blocks */
|
||||
article>section .org-src-container { /* make .org-src-container in ox-tufte.css more specific */
|
||||
max-width: var(--ox-tufte-fullwidth);
|
||||
width: var(--ox-tufte-fullwidth);
|
||||
}
|
||||
article > div.org-src-container { /* override .org-src-container in ox-tufte.css for toplevel */
|
||||
max-width: 90%;
|
||||
width: 90%;
|
||||
}
|
||||
/* END BONUS: fix top-level code blocks */
|
||||
/* END: width and placement of sidenotes + lists, epigraphs */
|
||||
|
||||
/* BEGIN: width of result blocks */
|
||||
article > pre.example {
|
||||
width: calc(97% * 0.9);
|
||||
margin-right: 10%;
|
||||
}
|
||||
section pre.example {
|
||||
width: calc(var(--ox-tufte-fullwidth) * 0.97);
|
||||
margin-left: calc(var(--ox-tufte-fullwidth) * 0.03);
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
section pre.example {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
/* END: width of result blocks */
|
||||
|
||||
/* BEGIN: fix horizontal scroll on small screens */
|
||||
.org-src-name {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
/* END: fix horizontal */
|
||||
|
||||
/* BEGIN: block margin notes */
|
||||
/***************************************************************************/
|
||||
/* block marginnotes - allows us to include lists, paragraphs, tables etc. */
|
||||
/***************************************************************************/
|
||||
article div { /* add missing default from tufte.css */
|
||||
font-size: var(--ox-tufte-content-font-size);
|
||||
line-height: var(--ox-tufte-content-line-height);
|
||||
}
|
||||
div.epigraph {
|
||||
/* NOTE: tufte.css has margins for epigraph in "em" which relies on font-size
|
||||
* for div element not being altered from default; otherwise epigraph margin
|
||||
* will scale with it (<https://zellwk.com/blog/rem-vs-em/>). now epigraphs,
|
||||
* unlike quotes don't have any business in the margin area. but if we did,
|
||||
* it wouldn't make sense to use the same margin absolutely. thus
|
||||
* blockquotes should be in 'em' instead of 'rem'. however, in order to get
|
||||
* same behaviour as tufte either the 'em' value will need to be modified
|
||||
* for epigraph or the font size specified for 'article div' will need to be
|
||||
* modified and will no longer be consistent with 'p'. */
|
||||
margin: var(--ox-tufte-content-epigraph-margin-vertical) 0;
|
||||
}
|
||||
div.marginnote dl,
|
||||
div.marginnote ol,
|
||||
div.marginnote p,
|
||||
div.marginnote ul {
|
||||
font-size: var(--ox-tufte-note-font-size);
|
||||
line-height: var(--ox-tufte-note-line-height);
|
||||
}
|
||||
div.marginnote p {
|
||||
margin-top: var(--ox-tufte-note-font-size);
|
||||
margin-bottom: var(--ox-tufte-note-font-size);
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
div.marginnote + *, /* needed for block marginnotes */
|
||||
h2, h3, h4, p { /* these are needed for margin/sidenotes in general */
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
/* END: block margin notes */
|
||||
|
||||
/* BEGIN: captions on figures */
|
||||
figure > figcaption { /* undo tufte-css tweaks, till they're better supported */
|
||||
max-width: unset;
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
/* undo tufte-css tweaks, till they're better supported */
|
||||
figure.fullwidth figcaption {
|
||||
margin-right: unset;
|
||||
}
|
||||
img.fullwidth + figcaption {
|
||||
width: var(--ox-tufte-fullwidth);
|
||||
}
|
||||
/* END: captions on figures */
|
||||
|
||||
/* BEGIN: fullwidth images */
|
||||
img.fullwidth {
|
||||
display: block;
|
||||
}
|
||||
/* END: fullwidth images */
|
||||
|
||||
/* BEGIN: prevent side-scroll when result of inline call is long */
|
||||
article code {
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
/* END: prevent side-scroll when result of inline call is long */
|
||||
Reference in New Issue
Block a user