Org: Add cover page option to LaTeX export

This commit is contained in:
TEC 2021-03-21 02:54:29 +08:00
parent a4690de72f
commit 05cbc446b5
Signed by: tec
GPG Key ID: 779591AFDB81F06C
1 changed files with 118 additions and 7 deletions

View File

@ -1,14 +1,15 @@
#+title: Doom Emacs Configuration
#+subtitle: The Methods, Management, and Menagerie of Madness
#+subtitle: The Methods, Management, and Menagerie@@latex:\\@@ of Madness@@latex: --- in meticulous detail@@
#+author: tecosaur
#+date: @@latex:\large@@ {{{modification-time(%Y-%m-%d %H:%M, t)}}} @@latex:\acr{\lowercase{@@{{{timezone}}}@@latex:}}@@, {{{git-rev}}}
#+date: @@html:<!--@@{{{git-rev}}}@@html:-->@@@@latex:\\\Large\bfseries@@ {{{modification-time(%Y-%m-%d, t)}}} @@latex:\\\normalsize\mdseries@@{{{modification-time(%H:%M, t)}}} @@latex:\acr{\lowercase{@@{{{timezone}}}@@latex:}}\iffalse@@, {{{git-rev}}}@@latex:\fi@@
#+macro: timezone (eval (substring (shell-command-to-string "date +%Z") 0 -1))
#+macro: git-rev (eval (format "@@html:<a href=\"https://github.com/tecosaur/emacs-config/commit/%1$s\" style=\"text-decoration: none\"><code style=\"padding: 0; color: var(--text-light); font-size: inherit; opacity: 0.7\">%1$s</code></a>@@@@latex:\\href{https://github.com/tecosaur/emacs-config/commit/%1$s}{\\normalsize\\texttt{%1$s}}@@" (substring (shell-command-to-string "git rev-parse --short HEAD") 0 -1)))
#+startup: fold
#+html_head: <link rel='shortcut icon' type='image/png' href='https://www.gnu.org/software/emacs/favicon.png'>
#+property: header-args:emacs-lisp :tangle yes :cache yes :results silent :comments link
#+property: header-args:shell :tangle "setup.sh"
#+property: header-args :tangle no :results silent
#+html_head: <link rel='shortcut icon' type='image/png' href='https://www.gnu.org/software/emacs/favicon.png'>
#+options: coverpage:yes
#+startup: fold
#+begin_export html
<a href="https://github.com/tecosaur/emacs-config/"
@ -19,9 +20,6 @@
style="height: 1em; position: relative; top: 0.1em;">
View on GitHub</a>
#+end_export
#+begin_export latex
\newpage % because the contents are multi-page, this looks better
#+end_export
#+begin_quote
Let us change our traditional attitude to the construction of programs:
@ -7375,7 +7373,120 @@ There are also some obsolete entries in the default value, specifically
("" "xcolor" nil) ; Generally useful
("" "hyperref" nil)))
#+end_src
**** Cover page
To make a nice cover page, a simple method that comes to mind is just redefining
=\maketitle=. To get precise control over the positioning we'll use the =tikz=
package, and then add in the Tikz libraries =calc= and =shapes.geometric= to make
some nice decorations for the background.
I'll start off by setting up the required additions to the preamble.
This will accomplish the following:
+ Load the required packages
+ Redefine =\maketitle=
+ Draw an Org icon with Tikz to use in the cover page (it's a little easter egg)
+ Start a new page after the table of contents by redefining =\tableofcontents=
#+name: latex-cover-page
#+begin_src LaTeX
\\usepackage{tikz}
\\usetikzlibrary{shapes.geometric}
\\usetikzlibrary{calc}
\\newsavebox\\orgicon
\\begin{lrbox}{\\orgicon}
\\begin{tikzpicture}[y=0.80pt, x=0.80pt, inner sep=0pt, outer sep=0pt]
\\path[fill=black!6] (16.15,24.00) .. controls (15.58,24.00) and (13.99,20.69) .. (12.77,18.06)arc(215.55:180.20:2.19) .. controls (12.33,19.91) and (11.27,19.09) .. (11.43,18.05) .. controls (11.36,18.09) and (10.17,17.83) .. (10.17,17.82) .. controls (9.94,18.75) and (9.37,19.44) .. (9.02,18.39) .. controls (8.32,16.72) and (8.14,15.40) .. (9.13,13.80) .. controls (8.22,9.74) and (2.18,7.75) .. (2.81,4.47) .. controls (2.99,4.47) and (4.45,0.99) .. (9.15,2.41) .. controls (14.71,3.99) and (17.77,0.30) .. (18.13,0.04) .. controls (18.65,-0.49) and (16.78,4.61) .. (12.83,6.90) .. controls (10.49,8.18) and (11.96,10.38) .. (12.12,11.15) .. controls (12.12,11.15) and (14.00,9.84) .. (15.36,11.85) .. controls (16.58,11.53) and (17.40,12.07) .. (18.46,11.69) .. controls (19.10,11.41) and (21.79,11.58) .. (20.79,13.08) .. controls (20.79,13.08) and (21.71,13.90) .. (21.80,13.99) .. controls (21.97,14.75) and (21.59,14.91) .. (21.47,15.12) .. controls (21.44,15.60) and (21.04,15.79) .. (20.55,15.44) .. controls (19.45,15.64) and (18.36,15.55) .. (17.83,15.59) .. controls (16.65,15.76) and (15.67,16.38) .. (15.67,16.38) .. controls (15.40,17.19) and (14.82,17.01) .. (14.09,17.32) .. controls (14.70,18.69) and (14.76,19.32) .. (15.50,21.32) .. controls (15.76,22.37) and (16.54,24.00) .. (16.15,24.00) -- cycle(7.83,16.74) .. controls (6.83,15.71) and (5.72,15.70) .. (4.05,15.42) .. controls (2.75,15.19) and (0.39,12.97) .. (0.02,10.68) .. controls (-0.02,10.07) and (-0.06,8.50) .. (0.45,7.18) .. controls (0.94,6.05) and (1.27,5.45) .. (2.29,4.85) .. controls (1.41,8.02) and (7.59,10.18) .. (8.55,13.80) -- (8.55,13.80) .. controls (7.73,15.00) and (7.80,15.64) .. (7.83,16.74) -- cycle;
\\end{tikzpicture}
\\end{lrbox}
\\makeatletter
\\g@addto@macro\\tableofcontents{\\clearpage}
\\renewcommand\\maketitle{
\\thispagestyle{empty}
\\hyphenpenalty=10000 % hyphens look bad in titles
\\renewcommand{\\baselinestretch}{1.1}
\\let\\oldtoday\\today
\\renewcommand{\\today}{\\LARGE\\number\\year\\\\\\large%
\\ifcase \\month \\or Jan\\or Feb\\or Mar\\or Apr\\or May \\or Jun\\or Jul\\or Aug\\or Sep\\or Oct\\or Nov\\or Dec\\fi
~\\number\\day}
\\begin{tikzpicture}[remember picture,overlay]
%% Background Polygons %%
\\foreach \\i in {2.5,...,22} % bottom left
{\\node[rounded corners,black!3.5,draw,regular polygon,regular polygon sides=6, minimum size=\\i cm,ultra thick] at ($(current page.west)+(2.5,-4.2)$) {} ;}
\\foreach \\i in {0.5,...,22} % top left
{\\node[rounded corners,black!5,draw,regular polygon,regular polygon sides=6, minimum size=\\i cm,ultra thick] at ($(current page.north west)+(2.5,2)$) {} ;}
\\node[rounded corners,fill=black!4,regular polygon,regular polygon sides=6, minimum size=5.5 cm,ultra thick] at ($(current page.north west)+(2.5,2)$) {};
\\foreach \\i in {0.5,...,24} % top right
{\\node[rounded corners,black!2,draw,regular polygon,regular polygon sides=6, minimum size=\\i cm,ultra thick] at ($(current page.north east)+(0,-8.5)$) {} ;}
\\node[fill=black!3,rounded corners,regular polygon,regular polygon sides=6, minimum size=2.5 cm,ultra thick] at ($(current page.north east)+(0,-8.5)$) {};
\\foreach \\i in {21,...,3} % bottom right
{\\node[black!3,rounded corners,draw,regular polygon,regular polygon sides=6, minimum size=\\i cm,ultra thick] at ($(current page.south east)+(-1.5,0.75)$) {} ;}
\\node[fill=black!3,rounded corners,regular polygon,regular polygon sides=6, minimum size=2 cm,ultra thick] at ($(current page.south east)+(-1.5,0.75)$) {};
\\node[align=center, scale=1.4] at ($(current page.south east)+(-1.5,0.75)$) {\\usebox\\orgicon};
%% Text %%
\\node[left, align=right, black, text width=0.8\\paperwidth, minimum height=3cm, rounded corners,font=\\Huge\\bfseries] at ($(current page.north east)+(-2,-8.5)$)
{\\@title};
\\node[left, align=right, black, text width=0.8\\paperwidth, minimum height=2cm, rounded corners, font=\\Large] at ($(current page.north east)+(-2,-11.8)$)
{\\scshape \\@author};
\\renewcommand{\\baselinestretch}{0.75}
\\node[align=center,rounded corners,fill=black!3,text=black,regular polygon,regular polygon sides=6, minimum size=2.5 cm,inner sep=0, font=\\Large\\bfseries ] at ($(current page.west)+(2.5,-4.2)$)
{\\@date};
\\end{tikzpicture}
\\let\\today\\oldtoday
\\clearpage}
\\makeatother
#+end_src
Now we've got a nice cover page to work with, we just need to use it every now
and then. Adding this to =#+options= feels most appropriate.
Let's have the =coverpage= option accept =auto= as a value and then decide whether
or not a cover page should be used based on the word count --- I'll have this be
the global default. Then we just want to insert a LaTeX snippet tweak the
subtitle format to use the cover page.
#+begin_src emacs-lisp :noweb no-export
(defvar org-latex-cover-page 'auto
"When t, use a cover page by default.
When auto, use a cover page when the document's wordcount exceeds
`org-latex-cover-page-wordcount-threshold'.
Set with #+option: coverpage:{yes,auto,no} in org buffers.")
(defvar org-latex-cover-page-wordcount-threshold 5000
"Document word count at which a cover page will be used automatically.
This condition is applied when cover page option is set to auto.")
(defvar org-latex-subtitle-coverpage-format "\\\\\\bigskip\n\\LARGE\\mdseries\\itshape\\color{black!80} %s\\par"
"Variant of `org-latex-subtitle-format' to use with the cover page.")
(defvar org-latex-cover-page-maketitle "
<<latex-cover-page>>
"
"LaTeX snippet for the preamble that sets \\maketitle to produce a cover page.")
(eval '(cl-pushnew '(:latex-cover-page nil "coverpage" org-latex-cover-page)
(org-export-backend-options (org-export-get-backend 'latex))))
(defun org-latex-cover-page-p ()
"Whether a cover page should be used when exporting this Org file."
(pcase (or (car
(delq nil
(mapcar
(lambda (opt-line)
(plist-get (org-export--parse-option-keyword opt-line 'latex) :latex-cover-page))
(cdar (org-collect-keywords '("OPTIONS"))))))
org-latex-cover-page)
((or 't 'yes) t)
('auto (when (> (count-words (point-min) (point-max)) org-latex-cover-page-wordcount-threshold) t))
(_ nil)))
(defadvice! org-latex-set-coverpage-subtitle-format-a (contents info)
"Set the subtitle format when a cover page is being used."
:before #'org-latex-template
(when (org-latex-cover-page-p)
(setf info (plist-put info :latex-subtitle-format org-latex-subtitle-coverpage-format))))
(add-to-list 'org-latex-feature-implementations '(cover-page :snippet org-latex-cover-page-maketitle :order 9) t)
(add-to-list 'org-latex-conditional-features '(org-latex-cover-page-p . cover-page) t)
#+end_src
**** Pretty code blocks
We could just use minted for syntax highlighting --- however, we can do better!