Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latex formatter with a custom Tex template #235

Open
traut opened this issue Aug 27, 2024 · 0 comments
Open

Latex formatter with a custom Tex template #235

traut opened this issue Aug 27, 2024 · 0 comments
Milestone

Comments

@traut
Copy link
Member

traut commented Aug 27, 2024

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

1.pdf

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant