emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[O] [PATCH] ox-latex: add optional-packages machinery


From: Aaron Ecay
Subject: [O] [PATCH] ox-latex: add optional-packages machinery
Date: Sun, 24 Feb 2013 13:50:17 -0500

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]