start to implement org export of custom article

This commit is contained in:
2021-02-16 16:10:13 +01:00
parent ea842bb955
commit 0e987ba777
3 changed files with 361 additions and 4 deletions

View File

@@ -453,8 +453,8 @@ file. See [Interlocking](https://www.emacswiki.org/info-ref?find=Interlocking) i
- when using this in an Org mode buffer:
`#+HEADER: :fit yes :imagemagick yes :iminoptions -density 300`
- can leads to:
- convert: attempt to perform an operation not allowed by the security policy \`gs’ @ error/delegate.c/ExternalDelegateCommand/378.
- convert: no images defined \`DESY<sub>logo</sub><sub>tikz.png</sub>&rsquo; @ error/convert.c/ConvertImageCommand/3282.
- ``convert: attempt to perform an operation not allowed by the security policy `gs' @ error/delegate.c/ExternalDelegateCommand/378.``
- ``convert: no images defined `DESY_logo_tikz.png' @ error/convert.c/ConvertImageCommand/3282.``
- edit `/etc/ImageMagick-7/policy.xml` and comment out
- `<policy domain="delegate" rights="none" pattern="gs" />`

View File

@@ -168,8 +168,8 @@ file. See [[https://www.emacswiki.org/info-ref?find=Interlocking][Interlocking]]
- when using this in an Org mode buffer:
=#+HEADER: :fit yes :imagemagick yes :iminoptions -density 300=
- can leads to:
- convert: attempt to perform an operation not allowed by the security policy `gs' @ error/delegate.c/ExternalDelegateCommand/378.
- convert: no images defined `DESY_logo_tikz.png' @ error/convert.c/ConvertImageCommand/3282.
- =convert: attempt to perform an operation not allowed by the security policy `gs' @ error/delegate.c/ExternalDelegateCommand/378.=
- =convert: no images defined `DESY_logo_tikz.png' @ error/convert.c/ConvertImageCommand/3282.=
- edit =/etc/ImageMagick-7/policy.xml= and comment out
- ~<policy domain="delegate" rights="none" pattern="gs" />~

357
lisp/my/my-org-article.el Normal file
View File

@@ -0,0 +1,357 @@
;;; 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