8000 Latex formatter with a custom Tex template · Issue #235 · blackstork-io/fabric · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Latex formatter with a custom Tex template #235
Open
@traut

Description

@traut

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0