chore(latex): rework templates for print varieties

This commit is contained in:
Steffen Jost 2023-03-08 17:45:28 +00:00
parent 32d56e30cc
commit 446ab76286
7 changed files with 383 additions and 60 deletions

View File

@ -10,6 +10,7 @@ module Handler.Admin.Test
import Import
import Utils.Print
import Utils.Print.Letters
import Handler.Utils
import Jobs

View File

@ -5,13 +5,10 @@
{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}
module Utils.Print
( pdfRenewal
, sendLetter, sendLetter'
( pdfRenewal, sendLetter' -- only used for test-letters triggered in route PrintSendR
, sendEmailOrLetter
, encryptPDF
, sanitizeCmdArg, validCmdArgument
, templateDIN5008
, templateRenewal
-- , compileTemplate, makePDF
, _Meta, addMeta
, toMeta, mbMeta -- single values
@ -68,40 +65,42 @@ import Utils.Print.RenewQualification
-- This is a hack to allow variable interpolation within a document.
-- Pandoc currently only allows interpolation within templates.
-- An alternative Route would be to use Builders, but this prevents User-edited Markup Templates
reTemplateLetter :: P.PandocMonad m => P.Meta -> StoredMarkup -> m Text
reTemplateLetter meta StoredMarkup{..} = do
tmpl <- compileTemplate strictMarkupInput
doc <- areader readerOpts strictMarkupInput
let writerOpts = def { P.writerExtensions = P.pandocExtensions
, P.writerTemplate = Just tmpl }
P.writeMarkdown writerOpts
$ appMeta setIsDeFromLang
$ addMeta meta doc
where
strictMarkupInput = toStrict markupInput
readerOpts = def { P.readerExtensions = P.pandocExtensions
, P.readerStripComments = True
}
-- reader :: (P.PandocMonad m, P.ToSources a) => P.ReaderOptions -> a -> m P.Pandoc
areader = case markupInputFormat of
MarkupHtml -> P.readHtml
MarkupMarkdown -> P.readMarkdown
MarkupPlaintext -> P.readMarkdown
-- reTemplateLetter :: P.PandocMonad m => P.Meta -> StoredMarkup -> m Text
-- reTemplateLetter meta StoredMarkup{..} = do
-- tmpl <- compileTemplate strictMarkupInput
-- doc <- areader readerOpts strictMarkupInput
-- let writerOpts = def { P.writerExtensions = P.pandocExtensions
-- , P.writerTemplate = Just tmpl }
-- P.writeMarkdown writerOpts
-- $ appMeta setIsDeFromLang
-- $ addMeta meta doc
-- where
-- strictMarkupInput = toStrict markupInput
-- readerOpts = def { P.readerExtensions = P.pandocExtensions
-- , P.readerStripComments = True
-- }
-- -- reader :: (P.PandocMonad m, P.ToSources a) => P.ReaderOptions -> a -> m P.Pandoc
-- areader = case markupInputFormat of
-- MarkupHtml -> P.readHtml
-- MarkupMarkdown -> P.readMarkdown
-- MarkupPlaintext -> P.readMarkdown
reTemplateLetter' :: P.PandocMonad m => P.Meta -> Text -> m Text
reTemplateLetter' meta md = do
tmpl <- compileTemplate md
doc <- P.readMarkdown readerOpts md
let writerOpts = def { P.writerExtensions = P.pandocExtensions
, P.writerTemplate = Just tmpl }
P.writeMarkdown writerOpts
$ appMeta setIsDeFromLang
$ addMeta meta doc
where
readerOpts = def { P.readerExtensions = P.pandocExtensions
, P.readerStripComments = True
}
-- reTemplateLetter' :: P.PandocMonad m => P.Meta -> Text -> m Text
-- reTemplateLetter' meta md = do
-- tmpl <- compileTemplate md
-- doc <- P.readMarkdown readerOpts md
-- let writerOpts = def { P.writerExtensions = P.pandocExtensions
-- , P.writerTemplate = Just tmpl }
-- P.writeMarkdown writerOpts
-- $ appMeta setIsDeFromLang
-- $ addMeta meta doc
-- where
-- readerOpts = def { P.readerExtensions = P.pandocExtensions
-- , P.readerStripComments = True
-- }
-- | read and writes markdown, applying it as its own template to apply meta
mdTemplating :: Text -> P.Meta -> HandlerFor UniWorX (Either P.PandocError Text)
mdTemplating template meta = runExceptT $ do
let readerOpts = def { P.readerExtensions = P.pandocExtensions
@ -179,7 +178,7 @@ mdRenewal meta = runExceptT $ do
$ addMeta meta doc
-- | combines 'mdRenewal' and 'pdfDIN5008'
-- | combines 'mdRenewal' and 'pdfDIN5008'; only user in PrintSendR Test Handler
pdfRenewal :: P.Meta -> HandlerFor UniWorX (Either Text LBS.ByteString)
pdfRenewal meta = do
e_txt <- mdRenewal' meta
@ -187,27 +186,47 @@ pdfRenewal meta = do
result <- actRight e_txt $ pdfDIN5008 meta
return $ over _Left P.renderError result
{-
-- | like pdfRenewal but without caching
pdfRenewal' :: P.Meta -> P.PandocIO LBS.ByteString
pdfRenewal' meta = do
doc <- reTemplateLetter' meta templateRenewal
pdfDIN5008' meta doc
-}
-- Generic Version
pdfLetter :: Text -> P.Meta -> HandlerFor UniWorX (Either Text LBS.ByteString)
pdfLetter :: Text -> P.Meta -> Handler (Either Text LBS.ByteString)
pdfLetter md meta = do
e_txt <- mdTemplating md meta
result <- actRight e_txt $ pdfDIN5008 meta
return $ over _Left P.renderError result
renderLetter :: (MDLetter l) => User -> l -> Handler (Either Text LBS.ByteString)
renderLetter rcvr mdl = do
now <- liftIO getCurrentTime
formatter@DateTimeFormatter{ format } <- getDateTimeFormatterUser' rcvr
let lang = selectDeEn $ rcvr & userLanguages -- select either German or English only, default de; see Utils.Lang
tmpl = getTemplate $ pure mdl
meta = letterMeta mdl formatter lang
<> mkMeta
[ toMeta "paper" ("TODO"::Text) -- TODO continue here
, toMeta "printid" ("TODO"::Text)
, toMeta "lang" lang
, toMeta "date" $ format SelFormatDate now
, toMeta "rcvr-name" $ rcvr & userDisplayName
, toMeta "address" $ fromMaybe [rcvr & userDisplayName] $ getPostalAddress rcvr
--, toMeta "rcvr-email" $ rcvr & userDisplayEmail -- note that some templates use "email" already otherwise
]
pdfLetter tmpl meta
---------------
-- PrintJobs --
---------------
-- DEPRECATED
-- Only used in print-test-handler for PrintSendR
sendLetter' :: Text -> LBS.ByteString -> (Maybe UserId, Maybe UserId) -> Maybe CourseId -> Maybe QualificationId -> Maybe LmsIdent -> DB (Either Text (Text, FilePath))
sendLetter' printJobName pdf (printJobRecipient, printJobSender) printJobCourse printJobQualification printJobLmsUser =
sendLetter pdf PrintJobIdentification

View File

@ -42,12 +42,33 @@ import Text.Hamlet
-- Hardcoded Templates --
-------------------------
templateRenewal :: Text
templateRenewal = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/fraport_renewal.md")
data LetterKind = Din5008 -- scrlttr2: Standard postal letter with address field, expects peprinted FraportLogo
| PinLetter -- Like Din5008, but for special paper with a protected pin field
| Plain -- scrartcl: Empty, expects empty paper with no preprints
| PlainLogo -- Like plain, but expects to be printed on paper with Logo
-- | Logo -- Like plain, but prints Fraport Logo in the upper right corner
deriving (Eq, Show)
templateLatex :: LetterKind -> Text
templateLatex =
let
tDin5008 = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008.latex")
tPinLetter = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008with_pin.latex")
tPlain = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/plain_article.latex")
in \case
PinLetter -> tPinLetter
Din5008 -> tDin5008
PlainLogo -> tPlain
Plain -> tPlain
-- | DEPRECATED TODO: remove
templateDIN5008 :: Text
templateDIN5008 = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/din5008.latex")
templateRenewal :: Text
templateRenewal = decodeUtf8 $(Data.FileEmbed.embedFile "templates/letter/fraport_renewal.md")
---------------

View File

@ -80,7 +80,7 @@ $endif$
%\usepackage[a4paper, bottom=8cm, top=3cm]{geometry} %%% THIS HAD NO EFFECT AT ALL
\usepackage{parskip}
%\usepackage{parskip}% might be useful for pandoc tightlist
\usepackage{graphics}
\usepackage{xcolor}
@ -120,7 +120,11 @@ $endif$
}
\setkomavar{fromphone}{$phone$}
\setkomavar{fromemail}{$email$}
\setkomavar{signature}{$author$}
%if there is a handwritten signature
%\setkomavar{signature}{$author$}
%if there is no handwritten signature
\setkomavar{signature}{}
\setplength{sigbeforevskip}{-\baselineskip}
\setkomavar{date}{$date$}
\setkomavar{place}{$place$}
@ -143,19 +147,9 @@ $endif$
\opening{$en-opening$}
$endif$
\begin{textblock}{65}(84,232)%hpos,vpos
\textcolor{black!39}{
\begin{labeling}{Password:}
$if(is-de)$
\item[Benutzer:] \texttt{$login$}
\item[Passwort:] \texttt{$pin$}
$else$
\item[User:] \texttt{$login$}
\item[Password:] \texttt{$pin$}
$endif$
\end{labeling}
~}
\end{textblock}
\begin{textblock}{65}(142,21)%hpos,vpos
\textcolor{white!0}{:::$paper$:::$printid$:::}%
\end{textblock}
$body$

View File

@ -0,0 +1,182 @@
%Based upon https://github.com/benedictdudel/pandoc-letter-din5008
\documentclass[
paper=A4,
foldmarks=BTm, % show foldmarks top, middle, bottom
foldmarks=false, % don't print foldmarks
fromalign=left, % letter head on the right
fromphone=true, % show phone number
fromemail=true, % show email
fromlogo=false, % don't show logo in letter head
version=last, % latest version of KOMA letter
pagenumber=botright, % show pagenumbers on bottom right
firstfoot=false % first-page footer
]{scrlttr2}
\PassOptionsToPackage{hyphens}{url}
\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\hypersetup{
$if(title-meta)$
pdftitle={$title-meta$},
$endif$
$if(author-meta)$
pdfauthor={$author-meta$},
$endif$
$if(lang)$
pdflang={$lang$},
$endif$
$if(subject)$
pdfsubject={$subject$},
$endif$
$if(keywords)$
pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$},
$endif$
}
\usepackage{url}
\usepackage{iftex}
%\usepackage[ngerman]{babel}
$if(lang)$
\ifLuaTeX
\usepackage[bidi=basic]{babel}
\else
\usepackage[bidi=default]{babel}
\fi
\babelprovide[main,import]{$babel-lang$}
$for(babel-otherlangs)$
\babelprovide[import]{$babel-otherlangs$}
$endfor$
% get rid of language-specific shorthands (see #6817):
\let\LanguageShortHands\languageshorthands
\def\languageshorthands#1{}
$endif$
\ifLuaTeX
\usepackage{selnolig} % disable illegal ligatures
\fi
\ifPDFTeX
\usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp} % provide euro and other symbols
\usepackage{DejaVuSansMono} % better monofont
\else
% if luatex or xetex
\usepackage{fontspec}
\setmonofont{DejaVu Sans Mono}
\fi
$if(mathspec)$
\ifXeTeX
\usepackage{mathspec}
\else
\usepackage{unicode-math}
\fi
$else$
\usepackage{unicode-math}
$endif$
%\usepackage[a4paper, bottom=8cm, top=3cm]{geometry} %%% THIS HAD NO EFFECT AT ALL
%\usepackage{parskip}% might be useful for pandoc tightlist
\usepackage{graphics}
\usepackage{xcolor}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage[right]{eurosym}
\usepackage{enumitem}
\makeatletter
\setplength{firstheadvpos}{1.8cm}
\setplength{toaddrvpos}{5.5cm}
\setlength{\@tempskipa}{-1.2cm}%
\@addtoplength{toaddrheight}{\@tempskipa}
\makeatother
\setlength{\oddsidemargin}{\useplength{toaddrhpos}}
\addtolength{\oddsidemargin}{-1in}
\setlength{\textwidth}{\useplength{firstheadwidth}}
\usepackage[absolute,quiet,overlay]{textpos}%,showboxes
\setlength{\TPHorizModule}{1mm}
\setlength{\TPVertModule}{1mm}
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\begin{document}%
\setkomavar{fromname}{$author$}%
\renewcommand*{\raggedsignature}{\raggedright}%
\setkomavar{fromaddress}{%
$for(return-address)$%
$return-address$$sep$\\
$endfor$
}
\setkomavar{fromphone}{$phone$}
\setkomavar{fromemail}{$email$}
%if there is a handwritten signature
%\setkomavar{signature}{$author$}
%if there is no handwritten signature
\setkomavar{signature}{}
\setplength{sigbeforevskip}{-\baselineskip}
\setkomavar{date}{$date$}
\setkomavar{place}{$place$}
$if(is-de)$
\setkomavar{subject}{$de-subject$}
$else$
\setkomavar{subject}{$en-subject$}
$endif$
\begin{letter}{%
$for(address)$
$address$$sep$\\
$endfor$
}
$if(is-de)$
\opening{$de-opening$}
$else$
\opening{$en-opening$}
$endif$
\begin{textblock}{65}(142,21)%hpos,vpos
\textcolor{white!0}{:::$paper$:::$printid$:::}%
\end{textblock}
\begin{textblock}{65}(84,232)%hpos,vpos
\textcolor{black!39}{
\begin{labeling}{Password:}
$if(is-de)$
\item[Benutzer:] \texttt{$login$}
\item[Passwort:] \texttt{$pin$}
$else$
\item[User:] \texttt{$login$}
\item[Password:] \texttt{$pin$}
$endif$
\end{labeling}
~}
\end{textblock}
$body$
$if(is-de)$
\closing{$de-closing$}
$else$
\closing{$en-closing$}
$endif$
%\ps $postskriptum$
$if(encludes)$
\setkomavar*{enclseparator}{Anlage}
\encl{$encludes$}
$endif$
\end{letter}
\end{document}

View File

@ -12,10 +12,10 @@ return-address:
de-opening: Liebe Fahrberechtigungsinhaber,
en-opening: Dear driver,
de-closing: |
Mit freundlichen Grüßen,
Mit freundlichen Grüßen,
Ihre Fahrerausbildung
en-closing: |
With kind regards,
With kind regards,
Your Fraport Driver Training
encludes:
hyperrefoptions: hidelinks
@ -29,11 +29,12 @@ lang: de-de
is-de: true
login: 123456
pin: abcdef
paper: pin
# Emfpänger
examinee: E. M. Pfänger
examinee: P. Rüfling
address:
- Musterfirma GmbH
- E. M. Pfänger
- Musterfirma GmbH
- Musterstraße 11
- 12345 Musterstadt
...

View File

@ -0,0 +1,105 @@
%Based upon https://github.com/benedictdudel/pandoc-letter-din5008
\documentclass[
paper=A4,
firstfoot=false % first-page footer
]{scrlttr2}
\PassOptionsToPackage{hyphens}{url}
\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\hypersetup{
$if(title-meta)$
pdftitle={$title-meta$},
$endif$
$if(author-meta)$
pdfauthor={$author-meta$},
$endif$
$if(lang)$
pdflang={$lang$},
$endif$
$if(subject)$
pdfsubject={$subject$},
$endif$
$if(keywords)$
pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$},
$endif$
}
\usepackage{url}
\usepackage{iftex}
%\usepackage[ngerman]{babel}
$if(lang)$
\ifLuaTeX
\usepackage[bidi=basic]{babel}
\else
\usepackage[bidi=default]{babel}
\fi
\babelprovide[main,import]{$babel-lang$}
$for(babel-otherlangs)$
\babelprovide[import]{$babel-otherlangs$}
$endfor$
% get rid of language-specific shorthands (see #6817):
\let\LanguageShortHands\languageshorthands
\def\languageshorthands#1{}
$endif$
\ifLuaTeX
\usepackage{selnolig} % disable illegal ligatures
\fi
\ifPDFTeX
\usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp} % provide euro and other symbols
\usepackage{DejaVuSansMono} % better monofont
\else
% if luatex or xetex
\usepackage{fontspec}
\setmonofont{DejaVu Sans Mono}
\fi
$if(mathspec)$
\ifXeTeX
\usepackage{mathspec}
\else
\usepackage{unicode-math}
\fi
$else$
\usepackage{unicode-math}
$endif$
%\usepackage[a4paper, bottom=8cm, top=3cm]{geometry} %%% THIS HAD NO EFFECT AT ALL
%\usepackage{parskip}% might be useful for pandoc tightlist
\usepackage{graphics}
\usepackage{xcolor}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage[right]{eurosym}
\usepackage{enumitem}
\setlength{\oddsidemargin}{\useplength{toaddrhpos}}
\addtolength{\oddsidemargin}{-1in}
\setlength{\textwidth}{\useplength{firstheadwidth}}
\usepackage[absolute,quiet,overlay]{textpos}%,showboxes
\setlength{\TPHorizModule}{1mm}
\setlength{\TPVertModule}{1mm}
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\begin{document}%
\begin{textblock}{65}(142,21)%hpos,vpos
\textcolor{white!0}{:::$paper$:::$printid$:::}%
\end{textblock}
$body$
\end{document}