emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Aaron Ecay <aaronecay@gmail.com>
To: emacs-orgmode@gnu.org
Subject: [PATCH] ox-latex: add optional-packages machinery
Date: Sun, 24 Feb 2013 13:50:17 -0500	[thread overview]
Message-ID: <1361731817-2363-1-git-send-email-aaronecay@gmail.com> (raw)
In-Reply-To: <87wqtx35x1.fsf@gmail.com>

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))))
+
 
 \f
 ;;; 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

      reply	other threads:[~2013-02-24 18:50 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-21  4:02 [RFC] [PATCH] conditional use of latex packages Aaron Ecay
2013-02-21  4:02 ` [PATCH 1/5] ox-latex: add optional-packages machinery Aaron Ecay
2013-02-21  4:02 ` [PATCH 2/5] ox-latex: convert source code and table export to use optional packages Aaron Ecay
2013-02-21  4:02 ` [PATCH 3/5] ob-R: change the file extension for tikz figures Aaron Ecay
2013-02-21  4:02 ` [PATCH 4/5] ox-latex: Treat tikz files as images Aaron Ecay
2013-02-21  4:02 ` [PATCH 5/5] ox-latex: Convert the image inclusion code to use optional packages Aaron Ecay
2013-02-21  9:51 ` [RFC] [PATCH] conditional use of latex packages Suvayu Ali
2013-02-21 15:19 ` Nicolas Goaziou
2013-02-21 17:33   ` Aaron Ecay
2013-02-21 18:39     ` Nicolas Goaziou
2013-02-24 18:47       ` Aaron Ecay
2013-02-24 18:50         ` Aaron Ecay [this message]

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=1361731817-2363-1-git-send-email-aaronecay@gmail.com \
    --to=aaronecay@gmail.com \
    --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).