Description
Background
As a prerequisite for well-formatted PDFs, we must have a Latex-formatted document. This means having a content-block level Latex formatters (for example, table
content block to render a Latex table) and a document-level formatted. This issue is about a document-level formatted.
Eisvogel template is awesome but it's too generic -- it tries to serve multiple use-cases and work with multiple PDF engines. We have an opportunity to be more opinionated and develop a better version to fit Fabric needs.
This issue depends on #262
Design
This issue contains a Go template that renders a Latex document that can be compiled into PDF. The PDF engine of choice is LuaTex.
Go template Latex document draft
% Fabric Latex template, to be rendered with lualatex
%
% Notes on content:
% - the very first title must be skipped, to avoid adding another nesting layer to TOC
% - content might include Latex controls -- `\pagebreak` for example
% - footnotes are not supported yet
\documentclass[
paper=a4,
]{scrartcl}
\usepackage{setspace}
\setstretch{1.2}
\usepackage{unicode-math} % this also loads fontspec
\defaultfontfeatures{Scale=MatchLowercase}
\defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
\setmainfont[]{ {{ .MainFont }} }
\setsansfont[]{ {{ .SansFont }} }
\setmonofont[]{ {{ .MonoFont }} }
\usepackage[]{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
% https://tex.stackexchange.com/questions/8351/what-do-makeatletter-and-makeatother-do
\makeatletter
% https://sourceforge.net/projects/koma-script/
\@ifundefined{KOMAClassName}{% if non-KOMA class
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}}
}{% if KOMA class
\KOMAoptions{parskip=half}}
\makeatother
% https://www.overleaf.com/learn/latex/Using_colors_in_LaTeX
\usepackage{xcolor}
\definecolor{default-linkcolor}{HTML}{ {{ .LinkColor }} }
\definecolor{default-filecolor}{HTML}{ {{ .FileLinkColor }} }
\definecolor{default-citecolor}{HTML}{ {{ .CiteColor }} }
\definecolor{default-urlcolor}{HTML}{ {{ .UrlColor }} }
\definecolor{default-toccolor}{HTML}{ {{ .TocLinkColor }} }
% Document geometry
\usepackage[{{ .DocGeometry }}]{geometry}
\usepackage[export]{adjustbox}
\usepackage{graphicx}
% ! https://github.com/catppuccin/latex
% themes? https://github.com/jez/latex-solarized
% See \lstdefinestyle in Eisvogel
\usepackage{listings, etoolbox}
% Stop code listing from breaking on page end
% https://tex.stackexchange.com/questions/88134/stop-listings-going-over-page-breaks
\BeforeBeginEnvironment{lstlisting}{\par\noindent\begin{minipage}{\linewidth}}
\AfterEndEnvironment{lstlisting}{\end{minipage}\par\addvspace{\topskip}}
% https://texdoc.org/serve/tabularray/0
\usepackage{longtable,tabulary,tabularray,booktabs,array}
\UseTblrLibrary{booktabs}
\usepackage{calc} % used for calculating minipage widths
%\makeatletter
%\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{}
%\makeatother
\usepackage{graphicx}
% Inspired by Eisvogel template:
\makeatletter
\newsavebox\customfabricbox
\newcommand*\fabricbounded[1]{% scales image to fit in text height/width
\sbox\customfabricbox{#1}%
\Gscale@div\@tempa{\textheight}{\dimexpr\ht\customfabricbox+\dp\customfabricbox\relax}%
\Gscale@div\@tempb{\linewidth}{\wd\customfabricbox}%
\ifdim\@tempb\p@<\@tempa\p@\let\@tempa\@tempb\fi% select the smaller of both
\ifdim\@tempa\p@<\p@\scalebox{\@tempa}{\usebox\customfabricbox}%
\else\usebox{\customfabricbox}%
\fi%
}
% Set default figure placement to htbp
% Make use of float-package and set default placement for figures to H.
% The option H means 'PUT IT HERE' (as opposed to the standard h option which means 'You may put it here if you like').
\usepackage{float}
\floatplacement{figure}{H}
\makeatother
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
% For Luatex
\usepackage{selnolig} % disable illegal ligatures
\usepackage{bookmark} % loads hyperref inside
\usepackage{xurl} % add URL line breaks if available
% Default settings print links in mono-style spaced fonts, this command changes
% that and displays the links in the same style as the rest of the text.
% https://www.overleaf.com/learn/latex/Hyperlinks
\urlstyle{same}
\hypersetup{
pdftitle={ {{ .Meta.Title }} },
pdfauthor={ {{ .Meta.Author }} },
colorlinks=true,
linkcolor={default-linkcolor},
filecolor={default-filecolor},
citecolor={default-citecolor},
urlcolor={default-urlcolor},
breaklinks=true,
pdfcreator={Fabric LaTeX}}
\usepackage{titling}
\title{ {{ .Meta.Title }} }
\author{ {{ .Meta.Author }} }
\date{ {{ .Meta.Date }} }
% for the background color of the title page
\usepackage{pagecolor}
% \usepackage{afterpage}
\usepackage{tikz} % graphing
% break urls
\PassOptionsToPackage{hyphens}{url}
% captions
\definecolor{caption-color}{HTML}{ {{ .CaptionColor }} }
\usepackage[font={stretch=1.2}, textfont={color=caption-color}, position=top, skip=4mm, labelfont=bf, singlelinecheck=false, justification=raggedright]{caption}
\setcapindent{0em}
% blockquote
\definecolor{blockquote-border}{HTML}{ {{ .BlockquoteBorderColor }} }
\definecolor{blockquote-text}{HTML}{ {{ .BlockquoteTextColor }} }
\usepackage{mdframed}
\newmdenv[rightline=false,bottomline=false,topline=false,linewidth={{ .BlockquoteBorderWidth }},linecolor=blockquote-border,skipabove=\parskip]{customblockquote}
\renewenvironment{quote}{\begin{customblockquote}\list{}{\rightmargin=0em\leftmargin=0em}%
\item\relax\color{blockquote-text}\ignorespaces}{\unskip\unskip\endlist\end{customblockquote}}
% Set heading color
\definecolor{heading-color}{HTML}{ {{ .HeadingColor }} }
\addtokomafont{section}{\color{heading-color}}
% Colors for tables
\definecolor{table-row-color}{HTML}{ {{ .TableRowColor }} }
\definecolor{table-rule-color}{HTML}{ {{ .TableRuleColor }} }
% ?
\usepackage{colortbl}
%\arrayrulecolor{table-rule-color} % color of \toprule, \midrule, \bottomrule
%\setlength\heavyrulewidth{0.3ex} % thickness of \toprule, \bottomrule
%\renewcommand{\arraystretch}{1.3} % spacing (padding)
% Set no paragraph indentation
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
\setlength{\emergencystretch}{3em} % prevent overfull lines
% Listing colors
% >>> see theme links above
\definecolor{listing-background}{HTML}{F7F7F7}
\definecolor{listing-rule}{HTML}{B3B2B3}
\definecolor{listing-numbers}{HTML}{B3B2B3}
\definecolor{listing-text-color}{HTML}{000000}
\definecolor{listing-keyword}{HTML}{435489}
\definecolor{listing-keyword-2}{HTML}{1284CA} % additional keywords
\definecolor{listing-keyword-3}{HTML}{9137CB} % additional keywords
\definecolor{listing-identifier}{HTML}{435489}
\definecolor{listing-string}{HTML}{00999A}
\definecolor{listing-comment}{HTML}{8E8E8E}
% Set header and footer
\usepackage[headsepline,footsepline]{scrlayer-scrpage}
\newpairofpagestyles{fabric-header-footer}{
\clearpairofpagestyles
\ihead*{ {{ .Meta.Title }} }
\chead*{}
\ohead*{ {{ .Meta.Date }} }
\ifoot*{ {{ .Meta.Author }} }
\cfoot*{}
\ofoot*{\thepage}
\addtokomafont{pageheadfoot}{\upshape}
}
\pagestyle{fabric-header-footer}
{{ if .BackgroundImage }}
% Background image
\usepackage[pages=all,placement=top]{background}
\backgroundsetup{
scale=1,
color=black,
opacity={{ .BackgroundImageOpacity }},
angle=0,
contents={%
\includegraphics[width=\paperwidth,height=\paperwidth]{ {{ .BackgroundImage }} }
}%
}
{{ end }}
% Print out the files used into the log
\listfiles
% ----------------------
\begin{document}
{{ if .WithTitlePage }}
%% Title page start
\begin{titlepage}
\newgeometry{top=2cm, right=4cm, bottom=3cm, left=4cm} % custom geometry for title page
\tikz[remember picture,overlay] \node[inner sep=0pt] at (current page.center){\includegraphics[width=\paperwidth,height=\paperheight]{ {{ .TitlePageBackgroundImage }} }};
\newcommand{\colorRule}[3][black]{\textcolor[HTML]{#1}{\rule{#2}{#3}}}
\begin{flushleft}
\noindent
\\[-1em]
\color[HTML]{ {{ .TitlePageTextColor }} }
\makebox[0pt][l]{\colorRule[{{ .TitlePageRuleColor }}]{1.3\textwidth}{4pt}}
\par
\noindent
% The titlepage with a background image has other text spacing and text size
{
\setstretch{2}
\vfill
\vskip -8em
\noindent {\huge \textbf{\textsf{ {{ .Meta.Title }} } } }
\vskip 2em
\noindent {\Large \textsf{ {{ .Meta.Author }} } \vskip 0.6em \textsf{ {{ .Meta.Date }} } }
\vfill
}
\noindent
\includegraphics[width={{ .TitlePageLogoWidth}}, left]{ {{ .TitlePageLogo }} }
\end{flushleft}
\end{titlepage}
\restoregeometry
\pagenumbering{arabic}
%% title page end
{{ end -}}
{{- if .WithToc -}}
{
\hypersetup{linkcolor=default-toccolor}
\setcounter{tocdepth}{ {{ .TocDepth }} }
\tableofcontents
{{ if .BreakAfterToc }}\newpage{{ end }}
}
{{- end -}}
{{ .Content }}
\end{document}
Data for the template
{
"Meta": {
"Title": "Test Report",
"Author": "John Doe",
"Date": "August 24, 2024"
},
"MainFont": "Helvetica",
"SansFont": "Tahoma",
"MonoFont": "Andale Mono",
"Theme": "dark",
"LinkColor": "A50000",
"FileLinkColor": "A50000",
"UrlColor": "A50000",
"CiteColor": "A50000",
"CaptionColor": "777777",
"BlockquoteBorderColor": "dddddd",
"BlockquoteTextColor": "777777",
"HeadingColor": "282828",
"TocLinkColor": "000000",
"TableRowColor": "F5F5F5",
"TableRuleColor": "999999",
"DocGeometry": "left=2cm,right=2cm,top=2.5cm,bottom=2.5cm",
"BackgroundImage": "./background-test.png",
"BackgroundImageOpacity": 0.4,
"BlockquoteBorderWidth": "3pt",
"WithTitlePage": true,
"TitlePageBackgroundImage": "./background-test.png",
"TitlePageTextColor": "1c2787",
"TitlePageRuleColor": "ff0d8a",
"TitlePageLogo": "../blackstork.png",
"TitlePageLogoWidth": "35mm",
"WithToc": true,
"BreakAfterToc": true,
"TocDepth": 3,
"CustomTexHeader": "",
"Content": "\\section{Title A}\\label{title-a}\n\n\\subsection{Title B}\\label{title-b}\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam interdum\neuismod sapien maximus viverra. Vestibulum malesuada ex sed erat viverra\nrhoncus. Integer congue nisl felis, vel facilisis diam commodo in.\n\n\\begin{lstlisting}[language=Python]\nprint(\"HELLO\")\n\\end{lstlisting}\n"
}
Rendered PDF
The template was rendered in Latex with tlp
and rendered into PDF with lualatex
:
$ cat manual-sample-data.json | tpl --file ./manual-sample.tex.gotmpl > 1.tex
$ lualatex 1.tex
References
- Eisvogel template for Pandoc