From mboxrd@z Thu Jan 1 00:00:00 1970 From: Aaron Ecay Subject: [PATCH] ox-latex: add optional-packages machinery Date: Sun, 24 Feb 2013 13:50:17 -0500 Message-ID: <1361731817-2363-1-git-send-email-aaronecay@gmail.com> References: <87wqtx35x1.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Return-path: Received: from eggs.gnu.org ([208.118.235.92]:39302) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U9gei-0006Fa-Is for emacs-orgmode@gnu.org; Sun, 24 Feb 2013 13:50:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U9ged-0001GQ-FF for emacs-orgmode@gnu.org; Sun, 24 Feb 2013 13:50:36 -0500 Received: from mail-qc0-f180.google.com ([209.85.216.180]:48412) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U9ged-0001GA-9y for emacs-orgmode@gnu.org; Sun, 24 Feb 2013 13:50:31 -0500 Received: by mail-qc0-f180.google.com with SMTP id v28so997262qcm.39 for ; Sun, 24 Feb 2013 10:50:30 -0800 (PST) In-Reply-To: <87wqtx35x1.fsf@gmail.com> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org This code allows latex packages to be inserted into the output document only if they are needed. The function ‘org-latex--record-package’ is provided for code to signal that it wants a package inserted into the output. The ‘org-latex-packages-(default-)alist’ variables are extended with an additional field, which indicates whether each package is to be loaded always, or only if requested by a call to ‘org-latex--record-package’. By default, all packages are loaded unconditionally (matching the present behavior). The ‘minted’, ‘longtable’, ‘listings’, ‘color’, ‘graphicx’, ‘booktabs’ and ‘wrapfig’ latex packages are requested when needed, so they may be set to load conditionally. --- lisp/org.el | 88 +++++++++++++++++++++++++++++++++++--------------------- lisp/ox-latex.el | 26 +++++++++++++++-- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 1d83aa4..51be09c 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -3735,34 +3735,40 @@ header, or they will be appended." (defun org-set-packages-alist (var val) "Set the packages alist and make sure it has 3 elements per entry." (set var (mapcar (lambda (x) - (if (and (consp x) (= (length x) 2)) - (list (car x) (nth 1 x) t) + (if (listp x) + (list (nth 0 x) + (nth 1 x) + (or (nth 2 x) t) + (nth 3 x)) x)) val))) (defun org-get-packages-alist (var) "Get the packages alist and make sure it has 3 elements per entry." (mapcar (lambda (x) - (if (and (consp x) (= (length x) 2)) - (list (car x) (nth 1 x) t) + (if (listp x) + (list (nth 0 x) + (nth 1 x) + (or (nth 2 x) t) + (nth 3 x)) x)) (default-value var))) (defcustom org-latex-default-packages-alist - '(("AUTO" "inputenc" t) - ("T1" "fontenc" t) - ("" "fixltx2e" nil) - ("" "graphicx" t) - ("" "longtable" nil) - ("" "float" nil) - ("" "wrapfig" nil) - ("" "soul" t) - ("" "textcomp" t) - ("" "marvosym" t) - ("" "wasysym" t) - ("" "latexsym" t) - ("" "amssymb" t) - ("" "hyperref" nil) + '(("AUTO" "inputenc" t nil) + ("T1" "fontenc" t nil) + ("" "fixltx2e" nil nil) + ("" "graphicx" t nil) + ("" "longtable" nil nil) + ("" "float" nil nil) + ("" "wrapfig" nil nil) + ("" "soul" t nil) + ("" "textcomp" t nil) + ("" "marvosym" t nil) + ("" "wasysym" t nil) + ("" "latexsym" t nil) + ("" "amssymb" t nil) + ("" "hyperref" nil nil) "\\tolerance=1000") "Alist of default packages to be inserted in the header. @@ -3786,9 +3792,12 @@ Therefore you should not modify this variable unless you know what you are doing. The one reason to change it anyway is that you might be loading some other package that conflicts with one of the default packages. Each cell is of the format -\( \"options\" \"package\" snippet-flag). If SNIPPET-FLAG is t, -the package also needs to be included when compiling LaTeX -snippets into images for inclusion into non-LaTeX output." +\(\"options\" \"package\" snippet-flag conditional-load). If +SNIPPET-FLAG is t, the package also needs to be included when +compiling LaTeX snippets into images for inclusion into non-LaTeX +output. If CONDITIONAL-LOAD is t, the package will be loaded +only if needed by the exporter (as signaled by calls to +`org-latex--use-package'.)" :group 'org-latex :group 'org-export-latex :set 'org-set-packages-alist @@ -3799,7 +3808,8 @@ snippets into images for inclusion into non-LaTeX output." (list :tag "options/package pair" (string :tag "options") (string :tag "package") - (boolean :tag "Snippet")) + (boolean :tag "Snippet") + (boolean :tag "Conditional load")) (string :tag "A line of LaTeX")))) (defcustom org-latex-packages-alist nil @@ -3808,11 +3818,13 @@ snippets into images for inclusion into non-LaTeX output." These will be inserted after `org-latex-default-packages-alist'. Each cell is of the format: - \(\"options\" \"package\" snippet-flag) + \(\"options\" \"package\" snippet-flag conditional-load) SNIPPET-FLAG, when t, indicates that this package is also needed when turning LaTeX snippets into images for inclusion into -non-LaTeX output. +non-LaTeX output. If CONDITIONAL-LOAD is t, the package will be +loaded only if needed by the exporter (as signaled by calls to +`org-latex--use-package'.) Make sure that you only list packages here which: @@ -3829,7 +3841,8 @@ Make sure that you only list packages here which: (list :tag "options/package pair" (string :tag "options") (string :tag "package") - (boolean :tag "Snippet")) + (boolean :tag "Snippet") + (boolean :tag "Conditional load")) (string :tag "A line of LaTeX")))) (defgroup org-appearance nil @@ -18246,7 +18259,7 @@ share a good deal of logic." (delete-file (concat texfilebase e)))) pngfile)))) -(defun org-splice-latex-header (tpl def-pkg pkg snippets-p &optional extra) +(defun org-splice-latex-header (tpl def-pkg pkg snippets-p &optional extra optional-pkgs) "Fill a LaTeX header template TPL. In the template, the following place holders will be recognized: @@ -18262,21 +18275,27 @@ holder is missing, the positive one (without the \"NO-\") will be assumed to be present at the end of the template. DEF-PKG and PKG are assumed to be alists of options/packagename lists. EXTRA is a string. -SNIPPETS-P indicates if this is run to create snippet images for HTML." +SNIPPETS-P indicates if this is run to create snippet images for HTML. +OPTIONAL-PKGS is the list of packages that the exporter used for this +document." (let (rpl (end "")) (if (string-match "^[ \t]*\\[\\(NO-\\)?DEFAULT-PACKAGES\\][ \t]*\n?" tpl) (setq rpl (if (or (match-end 1) (not def-pkg)) - "" (org-latex-packages-to-string def-pkg snippets-p t)) + "" (org-latex-packages-to-string + def-pkg snippets-p t optional-pkgs)) tpl (replace-match rpl t t tpl)) - (if def-pkg (setq end (org-latex-packages-to-string def-pkg snippets-p)))) + (if def-pkg (setq end (org-latex-packages-to-string + def-pkg snippets-p nil optional-pkgs)))) (if (string-match "\\[\\(NO-\\)?PACKAGES\\][ \t]*\n?" tpl) (setq rpl (if (or (match-end 1) (not pkg)) - "" (org-latex-packages-to-string pkg snippets-p t)) + "" (org-latex-packages-to-string + pkg snippets-p t optional-pkgs)) tpl (replace-match rpl t t tpl)) (if pkg (setq end (concat end "\n" - (org-latex-packages-to-string pkg snippets-p))))) + (org-latex-packages-to-string + pkg snippets-p nil optional-pkgs))))) (if (string-match "\\[\\(NO-\\)?EXTRA\\][ \t]*\n?" tpl) (setq rpl (if (or (match-end 1) (not extra)) @@ -18289,13 +18308,16 @@ SNIPPETS-P indicates if this is run to create snippet images for HTML." (concat tpl "\n" end) tpl))) -(defun org-latex-packages-to-string (pkg &optional snippets-p newline) +(defun org-latex-packages-to-string (pkg &optional snippets-p newline optional-pkgs) "Turn an alist of packages into a string with the \\usepackage macros." (setq pkg (mapconcat (lambda(p) (cond ((stringp p) p) ((and snippets-p (>= (length p) 3) (not (nth 2 p))) - (format "%% Package %s omitted" (cadr p))) + (format "%% Package %s omitted (for snippet)" (cadr p))) + ((and (>= (length p) 4) (nth 3 p) + (not (member (cadr p) optional-pkgs))) + (format "%% Package %s omitted (not needed)" (cadr p))) ((equal "" (car p)) (format "\\usepackage{%s}" (cadr p))) (t diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 9d5b5c5..0869a40 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -1087,6 +1087,11 @@ just outside of it." (funcall search-refs element)) "")) +(defun org-latex--record-package (info package) + (let ((optional-packages (plist-get info :latex-optional-packages))) + (plist-put info :latex-optional-packages + (add-to-list 'optional-packages package)))) + ;;; Template @@ -1119,7 +1124,8 @@ holding export options." document-class-string org-latex-default-packages-alist org-latex-packages-alist nil - (plist-get info :latex-header-extra))) + (plist-get info :latex-header-extra) + (plist-get info :latex-optional-packages))) info))))) ;; Possibly limit depth for headline numbering. (let ((sec-num (plist-get info :section-numbers))) @@ -1570,6 +1576,7 @@ contextual information." (concat "\\verb" separator code separator)) ;; Use minted package. ((eq org-latex-listings 'minted) + (org-latex--record-package info "minted") (let* ((org-lang (org-element-property :language inline-src-block)) (mint-lang (or (cadr (assq (intern org-lang) org-latex-minted-langs)) @@ -1582,6 +1589,8 @@ contextual information." separator code separator))) ;; Use listings package. (t + (org-latex--record-package info "listings") + (org-latex--record-package info "color") ;; Maybe translate language's name. (let* ((org-lang (org-element-property :language inline-src-block)) (lst-lang (or (cadr (assq (intern org-lang) @@ -1793,6 +1802,9 @@ used as a communication channel." ((eq float 'float) "[width=0.7\\textwidth]") ((eq float 'wrap) "[width=0.48\\textwidth]") (t ""))))) + (org-latex--record-package info "graphicx") + (when (eq float 'wrap) + (org-latex--record-package info "wrapfig")) ;; Return proper string, depending on FLOAT. (case float (wrap (format "\\begin{wrapfigure}%s @@ -2118,6 +2130,7 @@ contextual information." custom-env)) ;; Case 3. Use minted package. ((eq org-latex-listings 'minted) + (org-latex--record-package info "minted") (let ((float-env (when (or label caption) (format "\\begin{listing}[H]\n%%s\n%s\\end{listing}" @@ -2157,6 +2170,8 @@ contextual information." (if float-env (format float-env body) body))) ;; Case 4. Use listings package. (t + (org-latex--record-package info "listings") + (org-latex--record-package info "color") (let ((lst-lang (or (cadr (assq (intern lang) org-latex-listings-langs)) lang)) (caption-str @@ -2385,7 +2400,14 @@ This function assumes TABLE has `org' as its `:type' property and (placement (or (plist-get attr :placement) (format "[%s]" org-latex-default-figure-position))) (centerp (if (plist-member attr :center) (plist-get attr :center) - org-latex-tables-centered))) + org-latex-tables-centered)) + (booktabsp (if (plist-member attr :booktabs) + (plist-get attr :booktabs) + org-latex-tables-booktabs))) + (when (equal "longtable" table-env) + (org-latex--record-package info "longtable")) + (when booktabsp + (org-latex--record-package info "booktabs")) ;; Prepare the final format string for the table. (cond ;; Longtable. -- 1.8.1.4