Files
emacs/lisp/my/my-org-article.el

358 lines
13 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;;; my-org-article.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; EXAMPLE:
;; # -*- ispell-local-dictionary: "german" -*-
;;; Code:
(require 'ox-latex)
;;; Function Declarations
(defvar my-org-article-export-with-toc)
(defvar my-org-article-latex-default-packages-alist)
(defvar my-org-article-latex-packages-alist)
(defvar my-org-article-latex-compiler)
(defvar my-org-article-latex-default-class)
(defvar my-org-article-latex-default-class-options)
(defvar my-org-article-latex-header)
(defvar my-org-article-latex-header-extra)
(org-export-define-derived-backend 'article-latex 'latex
:menu-entry
'(?A "Export to LaTeX (Article)"
((?L "As LaTeX buffer" my-org-article-latex-export-as-latex)
(?l "As LaTeX file" my-org-article-latex-export-to-latex)
(?p "As PDF file" my-org-article-latex-export-to-pdf)
(?o "As PDF file and open"
(lambda (a s v b)
(if a (my-org-article-latex-export-to-pdf t s v b)
(org-open-file (my-org-article-latex-export-to-pdf nil s v b)))))))
:options-alist
'((:with-toc nil "toc" my-org-article-export-with-toc)
(:latex-class "LATEX_CLASS" nil my-org-article-latex-default-class t)
(:latex-class-options "LATEX_CLASS_OPTIONS" nil my-org-article-latex-default-class-options t)
(:latex-header "LATEX_HEADER" nil my-org-article-latex-header newline)
(:latex-header-extra "LATEX_HEADER_EXTRA" nil my-org-article-latex-header-extra newline)
(:latex-compiler "LATEX_COMPILER" nil my-org-article-latex-compiler t))
:translate-alist
'((template . my-org-article-latex-template))
)
;;; User Configurable Variables
(defgroup my-org-export-article nil
"Options for exporting Org mode files."
:tag "Org Export"
:group 'org)
(defcustom my-org-article-export-with-toc nil
"See `org-export-with-toc'."
:group 'my-org-export-article
:type '(choice
(const :tag "No Table of Contents" nil)
(const :tag "Full Table of Contents" t)
(integer :tag "TOC to level"))
:safe (lambda (x)
(or (booleanp x)
(integerp x))))
;;;; Compilation
(defcustom my-org-articel-latex-compiler "lualatex"
"See `org-latex-compiler'."
:group 'my-org-export-article
:type '(choice
(const :tag "pdfLaTeX" "pdflatex")
(const :tag "XeLaTeX" "xelatex")
(const :tag "LuaLaTeX" "lualatex")
(const :tag "Unset" ""))
:version "26.1"
:package-version '(Org . "9.0"))
;;;; Preamble
(defcustom my-org-article-latex-class "koma-letter"
"The default LaTeX class."
:group 'my-org-export-article
:type '(string :tag "LaTeX class"))
(defcustom my-org-article-latex-default-class-options "[enlargefirstpage]"
"The default LaTeX class options."
:group 'my-org-export-article
:type '(string :tag "LaTeX class"))
(add-to-list 'org-latex-classes
'("koma-letter" "\\documentclass{scrlttr2}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
(defcustom my-org-article-latex-header
"\\setlength{\\parskip}{6pt}
\\setlength{\\parindent}{0pt}
\\setlength{\\textheight}{22.5cm}
\\newcommand{\\fromassociation}{<<fromassociation>>}
\\newcommand{\\fromname}{<<fromname>>}
\\setkomavar{fromname}{\\fromname}
\\newcommand{\\fromstreet}{<<fromstreet>>}
\\newcommand{\\fromplace}{<<fromplace>>}
\\setkomavar{fromaddress}{\\fromstreet, \\fromplace}
\\setkomavar{fromphone}{<<fromphone>>}
\\setkomavar{fromurl}{<<fromurl>>}
\\setkomavar{fromemail}{<<fromemail>>}
\\setkomavar{place}{<<place>>}
\\newcommand\\toassociation{<<toassociation>>}
\\newcommand\\toname{<<toname>>}
\\newcommand\\tostreet{<<tostreet>>}
\\newcommand\\toplace{<<toplace>>}
\\newcommand\\subject{<<subject>>}
\\newcommand\\subjectextra{<<subjectextra>>}
% adjust some spacings
\\makeatletter
\\@setplength{toaddrwidth}{10cm}
\\makeatother
"
"Preamble options."
:group 'my-org-export-article)
(defcustom my-org-article-latex-header-extra ""
"Preamble extra options."
:group 'my-org-export-article)
(defcustom my-org-article-latex-default-packages-alist
'(("AUTO" "inputenc" t ("pdflatex"))
("T1" "fontenc" t ("pdflatex"))
("" "graphicx" t)
("" "grffile" t)
("" "longtable" nil)
("" "wrapfig" nil)
("" "rotating" nil)
("normalem" "ulem" t)
("" "amsmath" t)
("" "textcomp" t)
("" "amssymb" t)
("" "capt-of" nil)
("" "hyperref" nil)
;;
("ngerman" "babel" nil)
("utf8" "inputenc" nil)
("" "scrlayer-scrpage" nil)
)
"See `org-latex-default-packages-alist'."
:group 'my-org-export-article
;;:set 'org-set-packages-alist
;;:get 'org-get-packages-alist
:version "26.1"
:package-version '(Org . "8.3")
:type '(repeat
(choice
(list :tag "options/package pair"
(string :tag "options")
(string :tag "package")
(boolean :tag "Snippet")
(choice
(const :tag "For all compilers" nil)
(repeat :tag "Allowed compiler" string)))
(string :tag "A line of LaTeX"))))
(defcustom my-org-article-latex-packages-alist nil
"See `org-latex-packages-alist'."
:group 'my-org-export-article
;;:set 'org-set-packages-alist
;;:get 'org-get-packages-alist
:type '(repeat
(choice
(list :tag "options/package pair"
(string :tag "options")
(string :tag "package")
(boolean :tag "Snippet"))
(string :tag "A line of LaTeX"))))
;;;; Document
(defcustom my-org-letter-latex-opening
"\\firsthead{
\\begin{flushright}\\textsf{\\begin{tabular}{l}
\\fromassociation \\\\ \\usekomavar{fromname} \\\\ \\fromstreet \\\\
\\fromplace\\\\[3mm] \\usekomavar{fromphone} \\\\ \\usekomavar{fromemail}
\\end{tabular}}\\end{flushright}
}
% Kopf und Fußzeile der Folgeseiten
\\defpagestyle{nextpage}{{} {} {\\textsf{\\parbox{\\hsize}{\\usekomavar{fromname}\\today\\ \\hrulefill\\ \\pagename~\\thepage}}}}
{{} {} {}}
\\pagestyle{nextpage}
\\begin{letter}{Empfänger} % den Wert Empfänger nicht verändern
\\setkomavar{toname}{\\toassociation \\\\ \\toname}
\\setkomavar{toaddress}{\\tostreet \\\\ \\toplace}
\\setkomavar{subject}{\\subject \\\\ {\\normalfont \\subjectextra}}
\\opening{Sehr geehrter \\toname,}"
"Letter opening."
:group 'my-org-export-article)
(defcustom my-org-letter-latex-closing
"\\closing{Freundliche Grüße,}"
"Letter closing."
:group 'my-org-export-article)
;;; Template
;;;###autoload
(defun my-org-article-latex-make-preamble (info &optional template snippet?)
"See `org-latex-make-preamble'"
(let* ((class (plist-get info :latex-class))
(class-template
(or template
(let* ((class-options (plist-get info :latex-class-options))
(header (nth 1 (assoc class (plist-get info :latex-classes)))))
(and (stringp header)
(if (not class-options) header
(replace-regexp-in-string
"^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
class-options header t nil 1))))
(user-error "Unknown LaTeX class `%s'" class))))
(org-latex-guess-polyglossia-language
(org-latex-guess-babel-language
(org-latex-guess-inputenc
(org-element-normalize-string
(org-splice-latex-header
class-template
(org-latex--remove-packages my-org-letter-latex-default-packages-alist info)
(org-latex--remove-packages my-org-letter-latex-packages-alist info)
snippet?
(mapconcat #'org-element-normalize-string
(list (s-replace-all
(list (cons "<<fromassociation>>" (plist-get info :letter-from-association))
(cons "<<fromname>>" (plist-get info :letter-from-name))
(cons "<<fromstreet>>" (plist-get info :letter-from-street))
(cons "<<fromplace>>" (plist-get info :letter-from-place))
(cons "<<fromphone>>" (plist-get info :letter-from-phone))
(cons "<<fromurl>>" (plist-get info :letter-from-url))
(cons "<<fromemail>>" (plist-get info :letter-from-email))
(cons "<<toassociation>>" (plist-get info :letter-to-association))
(cons "<<toname>>" (plist-get info :letter-to-name))
(cons "<<tostreet>>" (plist-get info :letter-to-street))
(cons "<<toplace>>" (plist-get info :letter-to-place))
(cons "<<place>>" (plist-get info :letter-place))
(cons "<<date>>" (plist-get info :date))
(cons "<<subject>>" (string-replace "\n" "\\\\" (plist-get info :letter-subject)))
(cons "<<subjectextra>>" (string-replace "\n" "\\\\" (plist-get info :letter-subject-extra))))
(plist-get info :latex-header))
(and (not snippet?)
(plist-get info :latex-header-extra)))
""))))
info)
info)))
(defun my-org-article-latex-template (contents info)
"See `org-latex-template'"
(let ((title (org-export-data (plist-get info :title) info))
(spec (org-latex--format-spec info)))
(concat
;; Time-stamp.
(and (plist-get info :time-stamp-file)
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
;; LaTeX compiler.
(org-latex--insert-compiler info)
;; Document class and packages.
(my-org-letter-latex-make-preamble info)
;; Possibly limit depth for headline numbering.
(let ((sec-num (plist-get info :section-numbers)))
(when (integerp sec-num)
(format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
;; Author.
(let ((author (and (plist-get info :with-author)
(let ((auth (plist-get info :author)))
(and auth (org-export-data auth info)))))
(email (and (plist-get info :with-email)
(org-export-data (plist-get info :email) info))))
(cond ((and author email (not (string= "" email)))
(format "\\author{%s\\thanks{%s}}\n" author email))
((or author email) (format "\\author{%s}\n" (or author email)))))
;; Date.
(let ((date (and (plist-get info :with-date) (org-export-get-date info))))
(format "\\date{%s}\n" (org-export-data date info)))
;; Title and subtitle.
(let* ((subtitle (plist-get info :subtitle))
(formatted-subtitle
(when subtitle
(format (plist-get info :latex-subtitle-format)
(org-export-data subtitle info))))
(separate (plist-get info :latex-subtitle-separate)))
(concat
(format "\\title{%s%s}\n" title
(if separate "" (or formatted-subtitle "")))
(when (and separate subtitle)
(concat formatted-subtitle "\n"))))
;; Hyperref options.
(let ((template (plist-get info :latex-hyperref-template)))
(and (stringp template)
(format-spec template spec)))
;; Document start.
"\\begin{document}\n\n"
;; Title command.
(let* ((title-command (plist-get info :latex-title-command))
(command (and (stringp title-command)
(format-spec title-command spec))))
(org-element-normalize-string
(cond ((not (plist-get info :with-title)) nil)
((string= "" title) nil)
((not (stringp command)) nil)
((string-match "\\(?:[^%]\\|^\\)%s" command)
(format command title))
(t command))))
;; Table of contents.
(let ((depth (plist-get info :with-toc)))
(when depth
(concat (when (integerp depth)
(format "\\setcounter{tocdepth}{%d}\n" depth))
(plist-get info :latex-toc-command))))
;; Document's body.
(concat (plist-get info :letter-opening) "\n")
contents
(concat (plist-get info :letter-closing) "\n")
;; attachments
(let ((attachments (plist-get info :letter-attachment)))
(unless (string-equal attachments "")
(concat "\\vspace*{\\fill}\n"
"\\encl{" (string-replace "\n" "\\\\" attachments) "}\n")))
"\\end{letter}\n"
;; Creator.
(and (plist-get info :with-creator)
(concat (plist-get info :creator) "\n"))
;; Document end.
"\\end{document}")))
;;;###autoload
(defun my-org-article-latex-export-to-latex
(&optional async subtreep visible-only body-only ext-plist)
"See `org-latex-export-to-latex'"
(interactive)
(let ((outfile (org-export-output-file-name ".tex" subtreep)))
(org-export-to-file 'article-latex outfile
async subtreep visible-only body-only ext-plist)))
;;;###autoload
(defun my-org-article-latex-export-to-pdf
(&optional async subtreep visible-only body-only ext-plist)
"See `org-latex-export-to-pdf'"
(interactive)
(let ((outfile (org-export-output-file-name ".tex" subtreep)))
(org-export-to-file 'article-latex outfile
async subtreep visible-only body-only ext-plist
(lambda (file) (org-latex-compile file)))))
(provide 'my-org-article)
;;; my-org-article.el ends here