├── .github ├── .gitignore └── workflows │ ├── pkgdown.yaml │ └── R-CMD-check.yaml ├── .gitattributes ├── NAMESPACE ├── man ├── figures │ ├── logo.png │ ├── skeleton.png │ ├── letter_example1.png │ └── logo.svg └── komaletter.Rd ├── vignettes ├── signature.pdf ├── letter_example2.Rmd ├── letter_example0.Rmd ├── letter_example4.Rmd ├── letter_example3.Rmd ├── letter_example1.Rmd ├── pkgdown_letter_example4.Rmd ├── pkgdown_letter_example0.Rmd ├── pkgdown_letter_example2.Rmd ├── pkgdown_letter_example1.Rmd ├── pkgdown_letter_example3.Rmd ├── intro.Rmd └── parameterized_letter.Rmd ├── inst └── rmarkdown │ └── templates │ └── pdf │ ├── template.yaml │ ├── skeleton │ └── skeleton.Rmd │ └── resources │ ├── maintainersDelight.lco │ └── template.tex ├── .Rbuildignore ├── .gitignore ├── cran-comments.md ├── komaletter.Rproj ├── _pkgdown.yml ├── DESCRIPTION ├── NEWS.md ├── README.md └── R └── komaletter.R /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | data/* binary 3 | src/* text=lf 4 | R/* text=lf 5 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(komaletter) 4 | -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rnuske/komaletter/HEAD/man/figures/logo.png -------------------------------------------------------------------------------- /man/figures/skeleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rnuske/komaletter/HEAD/man/figures/skeleton.png -------------------------------------------------------------------------------- /vignettes/signature.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rnuske/komaletter/HEAD/vignettes/signature.pdf -------------------------------------------------------------------------------- /man/figures/letter_example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rnuske/komaletter/HEAD/man/figures/letter_example1.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/pdf/template.yaml: -------------------------------------------------------------------------------- 1 | name: komaletter (PDF) 2 | description: > 3 | A wrapper for the letter class scrlttr2 of the KOMA Script LaTeX bundle 4 | create_dir: false 5 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.drone\.yml$ 4 | ^\.gitattributes$ 5 | ^cran-comments\.md$ 6 | ^\.github$ 7 | ^docs$ 8 | ^pkgdown$ 9 | ^_pkgdown\.yml$ 10 | ^vignettes/pkgdown_ 11 | ^vignettes/intermediate.Rmd$ 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | docs 6 | vignettes/*.R 7 | vignettes/*.html 8 | vignettes/*.log 9 | vignettes/intermediate.Rmd 10 | vignettes/letter_example*.pdf 11 | vignettes/pkgdown_*.pdf 12 | vignettes/pkgdown_*.jpg 13 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | This is a minor update. 2 | 3 | The email address changed but maintainer stays the same 4 | 5 | This package checks okay locally on ubuntu 22.04 R-release, all win-builder flavors, macOS builder and Github Actions CI. 6 | 7 | Thanks for your great service 8 | Robert 9 | -------------------------------------------------------------------------------- /komaletter.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace,vignette 22 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://rnuske.github.io/komaletter 2 | 3 | template: 4 | bootstrap: 5 5 | 6 | navbar: 7 | structure: 8 | left: [intro, reference, articles, examples, news] 9 | components: 10 | intro: 11 | text: Get started 12 | href: articles/intro.html 13 | articles: 14 | text: Articles 15 | menu: 16 | - text: Introduction to komaletter 17 | href: articles/intro.html 18 | - text: Parameterized Letters for Mass Mailings 19 | href: articles/parameterized_letter.html 20 | examples: 21 | text: Examples 22 | menu: 23 | - text: Example 0 24 | href: articles/pkgdown_letter_example0.html 25 | - text: Example 1 26 | href: articles/pkgdown_letter_example1.html 27 | - text: Example 2 28 | href: articles/pkgdown_letter_example2.html 29 | - text: Example 3 30 | href: articles/pkgdown_letter_example3.html 31 | - text: Example 4 32 | href: articles/pkgdown_letter_example4.html 33 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/pdf/skeleton/skeleton.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | author: Max Mustermann 3 | return-address: 4 | - Musterstr. 12 5 | - 34567 Musterstadt 6 | address: 7 | - Robert Nuske 8 | - Hauptstr. 31 9 | - 30167 Hannover 10 | - Germany 11 | 12 | subject: Some nonsensical Subject 13 | opening: Dear Robert, 14 | closing: Best regards, 15 | signature: Max Mustermann 16 | 17 | output: komaletter::komaletter 18 | --- 19 | 20 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin mollis 21 | dolor vitae tristique eleifend. Quisque non ipsum sit amet velit 22 | malesuada consectetur. Praesent vel facilisis leo. Sed facilisis 23 | varius orci, ut aliquam lorem malesuada in. Morbi nec purus at nisi 24 | fringilla varius non ut dui. Pellentesque bibendum sapien velit. Nulla 25 | purus justo, congue eget enim a, elementum sollicitudin eros. Cras 26 | porta augue ligula, vel adipiscing odio ullamcorper eu. In tincidunt 27 | nisi sit amet tincidunt tincidunt. Maecenas elementum neque eget dolor 28 | egestas fringilla. 29 | 30 | Vestibulum id sodales lectus, sed scelerisque quam. Nullam auctor mi 31 | et feugiat commodo. Duis interdum imperdiet nulla, vitae bibendum eros 32 | placerat non. Cras ornare, risus in faucibus malesuada, libero sem 33 | fringilla quam, ut luctus enim sapien eget dolor. 34 | -------------------------------------------------------------------------------- /vignettes/letter_example2.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | author: Max Mustermann 3 | return-address: 4 | - Musterstr. 12 5 | - 34567 Musterstadt 6 | address: 7 | - Robert Nuske 8 | - Hauptstr. 31 9 | - 30167 Hannover 10 | - Germany 11 | 12 | subject: Letter in KOMA-Script's US Style 13 | opening: Dear Robert, 14 | closing: Best regards, 15 | signature: Max Mustermann 16 | 17 | lco: UScommercial9 18 | papersize: letter 19 | 20 | inline-links: true 21 | 22 | output: komaletter::komaletter 23 | 24 | vignette: > 25 | %\VignetteIndexEntry{komaletter example letter 2} 26 | %\VignetteKeywords{komaletter,vignette} 27 | %\VignettePackage{komaletter} 28 | %\VignetteEngine{knitr::rmarkdown} 29 | --- 30 | Perhaps a re-engineering of your current world view will re-energize 31 | your online nomenclature to enable a new holistic interactive 32 | enterprise internet communication solution. Upscaling the resurgent 33 | networking exchange solutions, achieving a breakaway systemic 34 | electronic data interchange system synchronization, thereby exploiting 35 | technical environments for mission critical broad based capacity 36 | constrained systems, such as the [**komaletter repo**](https://github.com/rnuske/komaletter). 37 | 38 | Fundamentally transforming well designed actionable information whose 39 | semantic content is virtually null. To more fully clarify the current 40 | exchange, a few aggregate issues will require thinking outside the box. 41 | -------------------------------------------------------------------------------- /vignettes/letter_example0.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | author: Max Mustermann 3 | return-address: 4 | - Musterstr. 12 5 | - 34567 Musterstadt 6 | address: 7 | - Robert Nuske 8 | - Hauptstr. 31 9 | - 30167 Hannover 10 | - Germany 11 | 12 | subject: Some nonsensical Subject 13 | opening: Dear Robert, 14 | closing: Best regards, 15 | signature: Max Mustermann 16 | 17 | output: komaletter::komaletter 18 | 19 | vignette: > 20 | %\VignetteIndexEntry{komaletter example letter 0} 21 | %\VignetteKeywords{komaletter,vignette} 22 | %\VignettePackage{komaletter} 23 | %\VignetteEngine{knitr::rmarkdown} 24 | --- 25 | 26 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin mollis 27 | dolor vitae tristique eleifend. Quisque non ipsum sit amet velit 28 | malesuada consectetur. Praesent vel facilisis leo. Sed facilisis 29 | varius orci, ut aliquam lorem malesuada in. Morbi nec purus at nisi 30 | fringilla varius non ut dui. Pellentesque bibendum sapien velit. Nulla 31 | purus justo, congue eget enim a, elementum sollicitudin eros. Cras 32 | porta augue ligula, vel adipiscing odio ullamcorper eu. In tincidunt 33 | nisi sit amet tincidunt tincidunt. Maecenas elementum neque eget dolor 34 | egestas fringilla. 35 | 36 | Vestibulum id sodales lectus, sed scelerisque quam. Nullam auctor mi 37 | et feugiat commodo. Duis interdum imperdiet nulla, vitae bibendum eros 38 | placerat non. Cras ornare, risus in faucibus malesuada, libero sem 39 | fringilla quam, ut luctus enim sapien eget dolor. 40 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: komaletter 2 | Title: Simply Beautiful PDF Letters from Markdown 3 | Version: 0.5.0 4 | Authors@R: c( 5 | person("Robert", "Nuske", role=c("aut", "cre"), 6 | email="robert.nuske@mailbox.org", 7 | comment=c(ORCID="0000-0001-9773-2061")), 8 | person("Dirk", "Eddelbuettel", role="aut", 9 | comment=c(ORCID="0000-0001-6419-907X")), 10 | person("Aaron", "Wolen", role="aut", 11 | comment=c(ORCID="0000-0003-2542-2202"))) 12 | Description: Write beautiful yet customizable letters in R Markdown and 13 | directly obtain the finished PDF. Smooth generation of PDFs is realized by 14 | 'rmarkdown', the 'pandoc-letter' template and the 'KOMA-Script' letter class. 15 | 'KOMA-Script' provides enhanced replacements for the standard 'LaTeX' classes 16 | with emphasis on typography and versatility. 'KOMA-Script' is particularly 17 | useful for international writers as it handles various paper formats well, 18 | provides layouts for many common window envelope types (e.g. German, US, 19 | French, Japanese) and lets you define your own layouts. The package comes 20 | with a default letter layout based on 'DIN 5008B'. 21 | License: GPL-3 22 | URL: https://rnuske.github.io/komaletter/, https://github.com/rnuske/komaletter 23 | BugReports: https://github.com/rnuske/komaletter/issues 24 | Encoding: UTF-8 25 | Depends: R (>= 3.0) 26 | Imports: rmarkdown (>= 0.6) 27 | Suggests: knitr (>= 1.8) 28 | VignetteBuilder: knitr 29 | Roxygen: list(markdown=TRUE) 30 | RoxygenNote: 7.2.3 31 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-tinytex@v2 28 | 29 | - uses: r-lib/actions/setup-r@v2 30 | with: 31 | use-public-rspm: true 32 | 33 | - uses: r-lib/actions/setup-r-dependencies@v2 34 | with: 35 | extra-packages: any::pkgdown, any::pdftools, local::. 36 | needs: website 37 | 38 | - name: Build site 39 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 40 | shell: Rscript {0} 41 | 42 | - name: Deploy to GitHub pages 🚀 43 | if: github.event_name != 'pull_request' 44 | uses: JamesIves/github-pages-deploy-action@v4.4.1 45 | with: 46 | clean: false 47 | branch: gh-pages 48 | folder: docs 49 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macos-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-tinytex@v2 37 | 38 | - uses: r-lib/actions/setup-r@v2 39 | with: 40 | r-version: ${{ matrix.config.r }} 41 | http-user-agent: ${{ matrix.config.http-user-agent }} 42 | use-public-rspm: true 43 | 44 | - uses: r-lib/actions/setup-r-dependencies@v2 45 | with: 46 | extra-packages: any::rcmdcheck 47 | needs: check 48 | 49 | - uses: r-lib/actions/check-r-package@v2 50 | with: 51 | upload-snapshots: true 52 | -------------------------------------------------------------------------------- /vignettes/letter_example4.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | author: Karl-Heinz Müller-Lüdenscheidt 3 | return-address: 4 | - Vicco-von-Bülow-Str. 3 5 | - 10623 Berlin-Charlottenburg 6 | return-short: Müller-Lüdenscheidt, Vicco-von-Bülow-Str. 3, 10623 Berlin 7 | 8 | address: 9 | - Dr. Klöbner 10 | - Musterstr. 12 11 | - 34567 Musterstadt 12 | 13 | subject: Usage of YAML parameter `return-short` 14 | opening: Dear Dr. Klöbner, 15 | closing: Sincerely, 16 | signature: Karl-Heinz Müller-Lüdenscheidt 17 | 18 | output: komaletter::komaletter 19 | 20 | vignette: > 21 | %\VignetteIndexEntry{komaletter example letter 4} 22 | %\VignetteKeywords{komaletter,vignette} 23 | %\VignettePackage{komaletter} 24 | %\VignetteEngine{knitr::rmarkdown} 25 | %\VignetteEncoding{UTF-8} 26 | --- 27 | 28 | this letter shows the usage of the YAML parameter `return-short`. The parameter 29 | has been created to allow for a different possibly shorter address to fit in 30 | the window. If `return-address` and `return-short` are used, the probably longer 31 | `return-address` is shown in the letterhead and the hopefully one line 32 | `return-short` in the address window. Usually (without using `return-short`) the 33 | address in the window is assembled from the `author` and the `return-address` 34 | and therefore identical to the address in the letterhead. 35 | 36 | The `return-short` must contain the entire return address shown in the window 37 | including the author name, since the author is not prepended. The YAML parameter 38 | `return-short` maybe either a one line text variable or a YAML sequence also 39 | known as list. 40 | 41 | ``` 42 | return-short: Müller-Lüdenscheidt, Vicco-von-Bülow-Str. 3, 10623 Berlin 43 | 44 | return-short: 45 | - Müller-Lüdenscheidt 46 | - Vicco-von-Bülow-Str. 3 47 | - 10623 Berlin 48 | ``` 49 | 50 | In the case of the one line text form the writer specifies the address 51 | separator, a comma in the above example. If `return-short` is given as a 52 | sequence / list, the address separator is defined in the relevant layout 53 | (`lco`-file). 54 | -------------------------------------------------------------------------------- /vignettes/letter_example3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | author: Dr. Robert Nuske 3 | return-address: 4 | - Hauptstr. 31 5 | - 30167 Hannover 6 | address: 7 | - Änderungsamt 8 | - Behördenstr. 24 9 | - 10557 Bärlin 10 | 11 | subject: Brief an eine Verwaltung 12 | opening: Sehr geehrte Damen und Herren, 13 | closing: Mit freundlichen Grüßen 14 | signature: "\\includegraphics{signature}" 15 | signature-before: 2mm 16 | 17 | yourref: IK 08/15 - 2 18 | yourmail: 23.02.2018 19 | myref: Äamt 2018-02 20 | date: 01.04.2018 21 | 22 | # no german language pack on CRAN => check fails 23 | # lang: de 24 | papersize: a4 25 | 26 | output: komaletter::komaletter 27 | 28 | vignette: > 29 | %\VignetteIndexEntry{komaletter example letter 3} 30 | %\VignetteKeywords{komaletter,vignette} 31 | %\VignettePackage{komaletter} 32 | %\VignetteEngine{knitr::rmarkdown} 33 | %\VignetteEncoding{UTF-8} 34 | --- 35 | 36 | überall dieselbe alte Leier. Das Layout ist fertig, der Text lässt auf 37 | sich warten. Damit das Layout nun nicht nackt im Raume steht und sich 38 | klein und leer vorkommt, springe ich ein: der Blindtext. Genau zu 39 | diesem Zwecke erschaffen, immer im Schatten meines großen Bruders 40 | "Lorem Ipsum", freue ich mich jedes Mal, wenn Sie ein paar Zeilen 41 | lesen. 42 | 43 | Und weil Sie nun schon die Güte haben, mich ein paar weitere Sätze 44 | lang zu begleiten, möchte ich diese Gelegenheit nutzen, Ihnen nicht 45 | nur als Lückenfüller zu dienen, sondern auf etwas hinzuweisen, das es 46 | ebenso verdient wahrgenommen zu werden: Webstandards nämlich. Sehen 47 | Sie, Webstandards sind das Regelwerk, auf dem Webseiten aufbauen. So 48 | gibt es Regeln für HTML, CSS, JavaScript oder auch XML. 49 | 50 | Diese Standards sorgen dafür, dass alle Beteiligten aus einer Webseite 51 | den größten Nutzen ziehen. Im Gegensatz zu früheren Webseiten müssen 52 | wir zum Beispiel nicht mehr zwei verschiedene Webseiten für den 53 | Internet Explorer und einen anderen Browser programmieren. Es reicht 54 | eine Seite, die - richtig angelegt - sowohl auf verschiedenen Browsern 55 | im Netz funktioniert, aber ebenso gut für den Ausdruck oder die 56 | Darstellung auf einem Handy geeignet ist. Wohlgemerkt: Eine Seite für 57 | alle Formate. 58 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # komaletter 0.5.900 2 | * longtables in pandoc > 2.11 needed updates in template.tex (mainly latex packages array and calc). 3 | 4 | # komaletter 0.5.0 5 | * added sections to default letter layout, since the employed KOMA-Script letter class `scrlttr2` has no sections. Just use `#`, `##`, `###` in your markdown and if you need section numbers set the YAML option `numbersections: true`. 6 | * enable References. If a bibliography is included in the YAML header and a citekey is used, a paragraph with a reference list gets added to the end of the text. 7 | * removed polyglossia from template.tex since newer pandoc does not support it anymore. 8 | 9 | # komaletter 0.4.2 10 | * fixed a redirected URL 11 | 12 | # komaletter 0.4.1 13 | * documented YAML-parameter `inline-links` for creating inline hyperlinks rather than footnotes 14 | * the default layout signals the PDF viewer to print the document at its actual size, which is followed by some. 15 | * notes on printing in README & vignette 16 | 17 | # komaletter 0.4 18 | * the default layout now also handles two-line return addresses gracefully 19 | * added YAML parameter `return-short` to define an additional shorter address 20 | just for the return address in window 21 | * enhanced documentation. roxygen documentation now written in markdown 22 | 23 | # komaletter 0.3.2 24 | * modified pandoc LaTeX template to consider that tex package 'grffile' might not be available. grffile is now a legacy package and was absent from TeX Live for a short time. (thanks @cderv) 25 | 26 | # komaletter 0.3.1 27 | * added a section to the intro vignette about non-English letters 28 | * slightly darker header and foldmarks in default style (maintainersDelight.lco) 29 | 30 | # komaletter 0.3 31 | * added vignette describing parameterized letters for mass mailings 32 | * reduced mandatory YAML metadata header items to 'output' (dispensed with 'opening', 'address', 'author') 33 | * introduced continuous integration service Travis CI 34 | 35 | # komaletter 0.2 36 | * protected path to default lco in LaTeX file against breaking at whitespace on windows 37 | * renamed maintainers_delight.lco to avoid pandoc problems with underscores in paths 38 | 39 | # komaletter 0.1 40 | * intial version based on linl version 0.0.2 but using KOMA-Script class 'scrlttr2' instead of LaTeX class 'letter' 41 | -------------------------------------------------------------------------------- /vignettes/letter_example1.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | author: Max Mustermann 3 | return-address: 4 | - Musterstr. 12 5 | - 34567 Musterstadt 6 | return-phone: +49-511-21311212 7 | return-email: max@musterman.tld 8 | 9 | address: 10 | - An Herrn 11 | - Robert Nuske 12 | - Hauptstr. 31 13 | - 30167 Hannover 14 | 15 | lco: "`r system.file('rmarkdown', 'templates', 'pdf', 'resources', 'maintainersDelight', package='komaletter')`" 16 | colorlinks: true 17 | 18 | date: 2020-12-31 19 | place: Musterstadt 20 | 21 | subject: Some Customizations 22 | opening: Hi Robert, 23 | closing: Cheers, 24 | signature: "\\includegraphics{signature}" 25 | signature-before: "0.5\\baselineskip" 26 | cc: Dirk Eddelbuettel 27 | ps: P.S. Beware of the copy editor! 28 | 29 | output: komaletter::komaletter 30 | 31 | vignette: > 32 | %\VignetteIndexEntry{komaletter example letter 1} 33 | %\VignetteKeywords{komaletter,vignette} 34 | %\VignettePackage{komaletter} 35 | %\VignetteEngine{knitr::rmarkdown} 36 | --- 37 | 38 | far far away, behind the word mountains, far from the countries 39 | Vokalia and Consonantia, there live the blind texts. Separated they 40 | live in Bookmarksgrove right at the coast of the Semantics, a large 41 | language ocean. A small river named Duden flows by their place and 42 | supplies it with the necessary regelialia. It is a paradisematic 43 | country, in which roasted parts of sentences [fly into your mouth](www.example.tld). 44 | 45 | Even the all-powerful Pointing has no control about the blind texts it 46 | is an almost unorthographic life One day however a small line of blind 47 | text by the name of Lorem Ipsum decided to leave for the far World of 48 | Grammar. The Big Oxmox advised her not to do so, because there were 49 | thousands of bad Commas, wild Question Marks and devious Semikoli, but 50 | the Little Blind Text didn't listen. 51 | 52 | She packed her seven versalia, put her initial into the belt and made 53 | herself on the way. When she reached the first hills of the Italic 54 | Mountains, she had a last view back on the skyline of her hometown 55 | Bookmarksgrove, the headline of Alphabet Village and the subline of 56 | her own road, the Line Lane. Pityful a rethoric question ran over her 57 | cheek, then she continued her way. On her way she met a copy. The copy 58 | warned the Little Blind Text, that where it came from it would have 59 | been rewritten a thousand times. 60 | -------------------------------------------------------------------------------- /vignettes/pkgdown_letter_example4.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Example 4" 3 | description: "Usage of YAML parameter return-short" 4 | output: html_document 5 | resource_files: [pkgdown_ex4.pdf] 6 | --- 7 | 8 | In addition to the YAML parameters shown in the first example, this example letter includes the parameter `return-short` which allows for a different, possibly shorter sender's address to fit in the envelope's window. 9 | 10 |
11 | 12 | ### RMarkdown of Letter 13 | 15 | 16 | ````markdown 17 | ```{r cars, results='asis', echo=FALSE} 18 | cat(paste(readLines('letter_example4.Rmd')[!grepl('ignette', x=readLines('letter_example4.Rmd'))], collapse ='\n')) 19 | ``` 20 | ```` 21 | 22 |
23 | 24 | ### Resulting PDF Letter 25 | 26 | The Letter rendered from above RMarkdown document via `rmarkdown::render()` or `RStudio Knit button` is shown below. The original PDF is also available. 27 | 28 | ```{r render-pdf, include=FALSE} 29 | rmarkdown::render("letter_example4.Rmd", output_file="pkgdown_ex4.pdf", output_dir='.') 30 | pdftools::pdf_convert(pdf='pkgdown_ex4.pdf', dpi=200, format="jpeg", pages=1, filenames="pkgdown_ex4.jpg") 31 | ``` 32 | 33 | Here should be an image of the PDF letter 34 | -------------------------------------------------------------------------------- /vignettes/pkgdown_letter_example0.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Example 0" 3 | description: "Template or Skeleton of a komaletter with a resonable small set of YAML parameters." 4 | output: html_document 5 | resource_files: [pkgdown_ex0.pdf] 6 | --- 7 | 8 | This example shows the skeleton you get when you run `rmarkdown::draft()` or start a letter from the template via the RStudio menu: File > New File > R Markdown... > From Template > komaletter (PDF). 9 | 10 | It is intended as a starting point for your own letters and comes with a reasonably small set of settings in the YAML header. Actually, you could omit everything except `output: komaletter::komaletter` and still get a formatted letter. 11 | 12 |
13 | 14 | ### RMarkdown of Letter 15 | 16 | ```{r show-code, code=readLines('letter_example0.Rmd')[!grepl('ignette', x=readLines('letter_example0.Rmd'))], eval=FALSE, highlight=FALSE} 17 | 18 | ``` 19 | 20 |
21 | 22 | ### Resulting PDF Letter 23 | 24 | The Letter rendered from above RMarkdown document via `rmarkdown::render()` or `RStudio Knit button` is shown below. The original PDF is also available. 25 | 26 | ```{r render-pdf, include=FALSE} 27 | rmarkdown::render("letter_example0.Rmd", output_file="pkgdown_ex0.pdf", output_dir='.') 28 | pdftools::pdf_convert(pdf='pkgdown_ex0.pdf', dpi=200, format="jpeg", pages=1, filenames="pkgdown_ex0.jpg") 29 | ``` 30 | 31 | Here should be an image of the PDF letter 32 | -------------------------------------------------------------------------------- /vignettes/pkgdown_letter_example2.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Example 2" 3 | description: "clickable links" 4 | output: html_document 5 | resource_files: [pkgdown_ex2.pdf] 6 | --- 7 | 8 | In addition to the YAML parameters shown in the first example, this letter displays some more parameters: 9 | 10 | * `lco` via this parameter you can specify your own letter layout in a **L**etter **C**lass **O**ption file or use one of the layouts predefined by KomaScript (see [Introduction to komaletter](./intro.html)). Here KomaScript's US Letter Style is used. 11 | * `papersize` to set a paper size other than DIN A4, here the US `letter`. 12 | * `inline-links` causes links to be *hot* / active / clickable in the PDF and not implemented as footnote. You are still responsible for the styling of the linked text, here done as bold text. 13 | 14 |
15 | 16 | ### RMarkdown of Letter 17 | 18 | ```{r show-code, code=readLines('letter_example2.Rmd')[!grepl('ignette', x=readLines('letter_example2.Rmd'))], eval=FALSE, highlight=FALSE} 19 | 20 | ``` 21 | 22 |
23 | 24 | ### Resulting PDF Letter 25 | 26 | The Letter rendered from above RMarkdown document via `rmarkdown::render()` or `RStudio Knit button` is shown below. The original PDF is also available. 27 | 28 | ```{r render-pdf, include=FALSE} 29 | rmarkdown::render("letter_example2.Rmd", output_file="pkgdown_ex2.pdf", output_dir='.') 30 | pdftools::pdf_convert(pdf='pkgdown_ex2.pdf', dpi=200, format="jpeg", pages=1, filenames="pkgdown_ex2.jpg") 31 | ``` 32 | 33 | Here should be an image of the PDF letter 34 | -------------------------------------------------------------------------------- /vignettes/pkgdown_letter_example1.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Example 1" 3 | desccription: "Setting the styling, include image of signature, supplement sender onfo, ps, cc and colorlinks" 4 | output: html_document 5 | resource_files: [pkgdown_ex1.pdf] 6 | --- 7 | 8 | In addition to the YAML parameters shown in the first example, this letter displays some more parameters 9 | 10 | * `lco` via this parameter you can specify your own letter layout in a **L**etter **C**lass **O**ption file or use one of the layouts predefined by KomaScript (see [Introduction to komaletter](./intro.html)). Here the path to the default lco of the komaletter package is given, resulting in the same layout as without this parameter. 11 | * image in `signature` to make it look like it was hand signed. 12 | * `signature-before` is for fine tuning the vertical space between closing and signature. 13 | * `return-phone`, `return-email` to supplement sender information. 14 | * `ps`, `cc` includes a *post scriptum* and a *carbon copy* address. 15 | * `colorlinks` causes URLs and the like to be displayed in color. 16 | 17 |
18 | 19 | ### RMarkdown of Letter 20 | 21 | ```{r show-code, code=readLines('letter_example1.Rmd')[!grepl('ignette', x=readLines('letter_example1.Rmd'))], eval=FALSE, highlight=FALSE} 22 | 23 | ``` 24 | 25 |
26 | 27 | ### Resulting PDF Letter 28 | 29 | The Letter rendered from above RMarkdown document via `rmarkdown::render()` or `RStudio Knit button` is shown below. The original PDF is also available. 30 | 31 | ```{r render-pdf, include=FALSE} 32 | rmarkdown::render("letter_example1.Rmd", output_file="pkgdown_ex1.pdf", output_dir='.') 33 | pdftools::pdf_convert(pdf='pkgdown_ex1.pdf', dpi=200, format="jpeg", pages=1, filenames="pkgdown_ex1.jpg") 34 | ``` 35 | 36 | Here should be an image of the PDF letter 37 | -------------------------------------------------------------------------------- /vignettes/pkgdown_letter_example3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Example 3" 3 | description: "reference line and language parameter" 4 | output: html_document 5 | resource_files: [pkgdown_ex3.pdf] 6 | --- 7 | 8 | In addition to the YAML parameters shown in the previous examples, this letter displays some additions needed for example when communicating with German administrations or agencies. 9 | 10 | * `yourref`, `yourmail`, `myref` common parts of the reference line (German: Bezugszeichenzeile) 11 | * image in `signature` to make it look like it was hand signed. 12 | * `signature-before` is for fine tuning the vertical space between closing and signature. 13 | * `lang` sets the language of the document which influences the labels of the reference line, date etc.. Requires the respective latex language pack (i.e texlive-lang-german). 14 | * `papersize` sets the paper size (default: DIN A4). 15 | 16 |
17 | 18 | ### RMarkdown of Letter 19 | ```{r manip_example, include=FALSE} 20 | ex <- readLines('letter_example3.Rmd') 21 | 22 | # drop vignette lines 23 | ex <- ex[!grepl('ignette', x=ex)] 24 | 25 | # replace language line and kill comment above 26 | idx <- grep("lang:", ex) 27 | ex[idx] <- "lang: de" 28 | ex <- ex[-(idx-1)] 29 | 30 | # write to file for rmarkdown::render() 31 | writeLines(ex, con="intermediate.Rmd") 32 | ``` 33 | 34 | 35 | ```{r show-rmarkdown, code=ex, eval=FALSE, highlight=FALSE} 36 | 37 | ``` 38 | 39 |
40 | 41 | ### Resulting PDF Letter 42 | 43 | The Letter rendered from above RMarkdown document via `rmarkdown::render()` or `RStudio Knit button` is shown below. The original PDF is also available. 44 | 45 | ```{r render-pdf, include=FALSE} 46 | rmarkdown::render("intermediate.Rmd", output_file="pkgdown_ex3.pdf", output_dir='.') 47 | pdftools::pdf_convert(pdf='pkgdown_ex3.pdf', dpi=200, format="jpeg", pages=1, filenames="pkgdown_ex3.jpg") 48 | ``` 49 | 50 | Here should be an image of the PDF letter 51 | -------------------------------------------------------------------------------- /man/komaletter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/komaletter.R 3 | \name{komaletter} 4 | \alias{komaletter} 5 | \title{KOMA-Script LaTeX Letter Format} 6 | \usage{ 7 | komaletter(..., keep_tex = FALSE) 8 | } 9 | \arguments{ 10 | \item{...}{Additional arguments to \code{\link[rmarkdown:pdf_document]{rmarkdown::pdf_document()}}} 11 | 12 | \item{keep_tex}{A boolean toggle to select whether intermediate 13 | LaTeX files are to be kept, defaults to \code{FALSE}} 14 | } 15 | \value{ 16 | R Markdown output to pass to \code{\link[rmarkdown:render]{rmarkdown::render()}} 17 | } 18 | \description{ 19 | A format for LaTeX letters via R Markdown using the KOMA-Script class 20 | 'scrlttr2'. It provides layouts for many different window envelope types 21 | (German, US, French, Japanese, ...) and lets you define customized layouts. 22 | } 23 | \section{Letter features}{ 24 | Various aspects of the letter can be customized via the following 25 | variables in the R Markdown document metadata (aka YAML header). 26 | 27 | Although it rarely makes sense to write a letter without sender and recipient, 28 | a komaletter can be constructed by merely specifying the output format. 29 | All other variables are optional. 30 | 31 | Most commonly used variables:\tabular{ll}{ 32 | \strong{Variable} \tab \strong{Description} \cr 33 | author \tab Writer of the letter. \cr 34 | return-address \tab Address of the sender; takes a list for a multi-line address. \cr 35 | address \tab Name and address of the recipient; takes a list. \cr 36 | date \tab Custom date; if not specified, current date will be inserted. \cr 37 | subject \tab Subject line. \cr 38 | opening \tab Text for the salutation. \cr 39 | closing \tab Text for the complementary close, like: Best regards. \cr 40 | signature \tab Text (e.g. your name) or an image of your signature with \code{"\\\\includegraphics{sig.png}"}. \cr 41 | signature-before \tab Adjust vertical space between closing and signature by specifying a length such as \verb{2mm} or \code{"0.5\\\\baselineskip"}. \cr 42 | } 43 | 44 | 45 | All variables understood by \code{rmarkdown}'s \code{pdf_document} format may be used 46 | in addition to the \code{komaletter} variables defined in the following table 47 | to further customize your letter. For modifications of the layout please 48 | refer to the vignette "Introduction to komaletter". 49 | 50 | Further variables defined by komaletter:\tabular{ll}{ 51 | \strong{Variable} \tab \strong{Description} \cr 52 | lco \tab Letter Class Option File. Either name of a standard KOMA-Script LCO (e.g. DIN, SN, ) or path to custom LCO. If not specified, the \code{maintainersDelight.lco} will be used. \cr 53 | lang \tab Language code according to \href{https://www.rfc-editor.org/rfc/rfc5646.html}{BCP 47} (e.g. \code{en} or \code{en-GB}). \cr 54 | papersize \tab Size of paper eg. \code{a4}, \code{letter}. \cr 55 | return-phone \tab Phone number of sender used in letter head. \cr 56 | return-email \tab Email address of sender used in letter head. \cr 57 | return-url \tab Website of sender used in letter head. \cr 58 | return-short \tab Shorter version of return address only used in window (see vignette \code{letter_example4}). \cr 59 | place \tab Sender’s place used near date. \cr 60 | yourref \tab Addressee’s reference as part of reference line. \cr 61 | yourmail \tab Date of addressee’s referenced mail as part of reference line. \cr 62 | myref \tab Sender’s reference as part of reference line. \cr 63 | customer \tab Customer number as part of reference line. \cr 64 | invoice \tab Invoice number as part of reference line. \cr 65 | cc \tab Recipients to be carbon-copied; can take a list. \cr 66 | encl \tab List of enclosures. \cr 67 | ps \tab Text to be added at the end of the letter as a postscript. \cr 68 | inline-links \tab If true, do standard inline hyperlinks rather than footnotes (styling is author's job, cf. vignette \code{letter_example2}). \cr 69 | komaoption \tab Specify further KOMA options; takes a list (see \href{https://komascript.de/~mkohm/scrguien.pdf}{KOMA-Script documentation}). \cr 70 | parskip \tab Defines how to mark new paragraphs, e.g. full, half, off (see \href{https://komascript.de/~mkohm/scrguien.pdf}{KOMA-Script documentation}). \cr 71 | } 72 | 73 | 74 | The source of the example letter vignettes show several of these options in use. 75 | } 76 | 77 | \examples{ 78 | \dontrun{ 79 | rmarkdown::draft("my_letter.Rmd", template="pdf", package="komaletter") 80 | rmarkdown::render("my_letter.Rmd") 81 | } 82 | 83 | } 84 | \references{ 85 | JJ Allaire, Yihui Xie, Jonathan McPherson et al. (2020). rmarkdown: 86 | Dynamic Documents for R. R package version 2.6. 87 | \url{https://cran.r-project.org/package=rmarkdown} 88 | 89 | Aaron Wolen and Andrew Dunning (2017). pandoc-letter. GitHub Repository. 90 | \url{https://github.com/aaronwolen/pandoc-letter} 91 | 92 | Markus Kohm (2020). KOMA-Script: A versatile LaTeX \eqn{2_\epsilon}{2\epsilon} bundle. 93 | \url{https://komascript.de/~mkohm/scrguien.pdf} 94 | } 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # komaletter: Simply Beautiful PDF Letters from Markdown 2 | 3 | 4 | [![R-CMD-check](https://github.com/rnuske/komaletter/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rnuske/komaletter/actions/workflows/R-CMD-check.yaml) 5 | [![Package-License](https://img.shields.io/badge/license-GPL--3-brightgreen.svg?style=flat)](https://www.gnu.org/licenses/gpl-3.0.html) 6 | [![CRAN](https://www.r-pkg.org/badges/version/komaletter)](https://cran.r-project.org/package=komaletter) 7 | [![Dependencies](https://tinyverse.netlify.app/badge/komaletter)](https://cran.r-project.org/package=komaletter) 8 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1221316.svg)](https://doi.org/10.5281/zenodo.1221316) 9 | 10 | 11 | 12 | ### Motivation 13 | Simple letters tend to look very much alike. They are either determined by a 14 | standard eg. window envelope style or writer's preferences. Since the layout 15 | is fixed, letters can be written perfectly in R Markdown. 16 | 17 | The [KOMA-Script LaTeX Bundle](https://www.komascript.de) provides layouts for 18 | many common window envelope types (German, US, French, Japanese, ...) and the 19 | possibility to define your own layout. The *komaletter* package also provides 20 | it's own default letter layout loosely based on DIN 5008B. 21 | 22 | This package is an adaptation of the 23 | [linl](https://cran.r-project.org/package=linl) package 24 | for international writers. linl itself is based on the 25 | [pandoc-letter](https://github.com/aaronwolen/pandoc-letter) 26 | template and extends it for use from R via the 27 | [rmarkdown](https://cran.r-project.org/package=rmarkdown) package. 28 | 29 | 30 | ### Examples 31 | 32 | #### Skeleton 33 | The skeleton provided by `komaletter` creates a very simple letter as a 34 | starting point for your own writing. Several formatting defaults such as font, 35 | fontsize, indentation are in use. See `vignette('intro', 'komaletter')` and 36 | `help(komaletter)` for a complete list and their default values. The following 37 | figure shows the `rmarkdown` source on the left and the rendered `pdf` on the 38 | right. 39 | 40 | ![](man/figures/skeleton.png) 41 | 42 | 43 | #### Vignette 44 | The vignette examples are a bit more detailed and s demonstrate, for example, 45 | how to include a signature, choose a different layout and make some format 46 | settings. All of these are driven by simple settings in the `YAML` header as 47 | shown in the following figure on the left. 48 | 49 | ![](man/figures/letter_example1.png) 50 | 51 | 52 | ### Usage 53 | To start a new letter you can take advantage of the komaletter skeleton via 54 | `rmarkdown::draft()` or the RStudio menu: File > New File > R Markdown... > 55 | From Template > komaletter (PDF). 56 | When finished writing your letter the RMarkdown document can be rendered to PDF 57 | via `rmarkdown::render()` or the RStudio Knit button. 58 | 59 | ```r 60 | # start a new letter using the provided skeleton 61 | rmarkdown::draft("my_letter.Rmd", template="pdf", package="komaletter", edit=FALSE) 62 | 63 | # change my_letter.Rmd to your liking 64 | 65 | # turn Rmd into a beautiful PDF 66 | rmarkdown::render("my_letter.Rmd") 67 | ``` 68 | 69 | 70 | ### About Printing 71 | Some PDF viewers do not realize that the document already has a blank margin and scale or 'fit to page' for printing. This generally results in smaller fonts, overly large margins, broken layout and most importantly a misplaced address. In the worst case, parts of the address are not visible in the window of the envelope. 72 | 73 | komaletter's default layout signals the PDF viewer to print the document at its actual size. Unfortunately, not many PDF viewers heed this hint. 74 | 75 | Thus, before printing the document, you should check that the document is not shrunk or 'fit to page'. **The document must be printed at its actual size / 100%** so that the positions of the elements are correct. 76 | 77 | 78 | ### Installation 79 | You can install the released version of **komaletter** from [CRAN](https://CRAN.R-project.org/package=komaletter) with 80 | 81 | ``` r 82 | install.packages("komaletter") 83 | ``` 84 | 85 | and the development version from [GitHub](https://github.com/rnuske/komaletter) 86 | using the package `remotes` 87 | 88 | ``` r 89 | remotes::install_github("rnuske/komaletter") 90 | ``` 91 | 92 | 93 | ### Requirements 94 | Beyond the R package dependency `rmarkdown`, a working `pandoc` binary and a 95 | `LaTeX` distribution including `KOMA-Script` is needed. RStudio installs it's 96 | own copy of `pandoc`, otherwise do what is needed on your OS. As for LaTeX look 97 | for `texlive` which is included in most Linux distributions. KOMA-Script is 98 | part of all but the most bare bone LaTeX distributions. Something like 99 | `sudo apt install pandoc pandoc-citeproc texlive` should provide everything 100 | needed on Debian/Ubuntu. To get a working LaTeX on Windows it is recommended 101 | to use the service of the R package `tinytex`. 102 | 103 | If you plan to write non-english letters, make sure you have the necessary 104 | language packs, _i.e._ `texlive-lang-german`. 105 | 106 | 107 | ### Authors 108 | Robert Nuske, Dirk Eddelbuettel and Aaron Wolen. 109 | 110 | 111 | ### License 112 | GPL-3 for this package, the work in [pandoc-letter](https://github.com/aaronwolen/pandoc-letter), as well as the underlying Pandoc template. 113 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/pdf/resources/maintainersDelight.lco: -------------------------------------------------------------------------------- 1 | \ProvidesFile{maintainersDelight.lco}[letter class options to maintainers delight] % loosely follows DIN 5008B 2 | 3 | \LoadLetterOption{DIN} % the default but let's be explicit about our foundation 4 | 5 | 6 | % Options -------------------------------------------------------------------- 7 | \KOMAoptions{% 8 | parskip=half, % half line skip between paragraphs 9 | firstfoot=false, % no footer 10 | enlargefirstpage, % longer first page works well with no footer 11 | refline=narrow, % adjust refline with text body 12 | backaddress=plain % do not underline backaddress in address window 13 | } 14 | 15 | 16 | % Fonts, Icons and Colors ----------------------------------------------------- 17 | \renewcommand{\familydefault}{\sfdefault} % sans serif font for entire letter 18 | \usepackage{lmodern} 19 | 20 | \usepackage{marvosym} % icons 21 | \usepackage[dvipsnames]{xcolor} % custom colors 22 | \usepackage{ragged2e} % aligned AND correctly hyphenated 23 | 24 | \setkomafont{backaddress}{\fontsize{8pt}{8pt}\selectfont} 25 | \setkomafont{refname}{\fontsize{8pt}{8pt}\selectfont} 26 | \setkomafont{refvalue}{\fontsize{10pt}{10pt}\selectfont} 27 | \setkomafont{foldmark}{\color[gray]{0.50}} 28 | 29 | % with ideas from https://tex.stackexchange.com/a/550095/218581 https://tex.stackexchange.com/a/550178/218581 https://tex.stackexchange.com/a/78919/218581 30 | \newcommand*{\addverythinspace}{\hskip0.02083em\relax} 31 | \setkomavar{backaddressseparator}{\nobreak\addverythinspace\textperiodcentered\addverythinspace} 32 | \setkomavar{backaddress}{\parbox[c]{\useplength{toaddrwidth}}{% 33 | {\def\\{\usekomavar{backaddressseparator}\@ogobble}% 34 | \usekomavar{fromname}\usekomavar{backaddressseparator}\usekomavar{fromaddress}}% 35 | \RaggedRight% 36 | }} 37 | 38 | 39 | % Layout ---------------------------------------------------------------------- 40 | % Text block 41 | \areaset{160mm}{237mm} % width and height of textarea 42 | \setlength{\oddsidemargin}{\dimexpr 30mm-1in} % left margin 30mm 43 | \setlength{\evensidemargin}{\dimexpr 20mm-1in} % right margin 20mm 44 | 45 | % Letter Head 46 | \@setplength{firstheadhpos}{30mm} 47 | \@setplength{firstheadvpos}{17mm} 48 | \@setplength{firstheadwidth}{\textwidth} 49 | 50 | % Address Window 51 | \@setplength{toaddrhpos}{30mm} 52 | \@setplength{toaddrvpos}{45mm} 53 | \@setplength{toaddrwidth}{75mm} 54 | \@setplength{toaddrheight}{45mm} 55 | \@setplength{toaddrindent}{0mm} 56 | \@setplength{backaddrheight}{16pt} 57 | 58 | % Foldmarks 59 | \@setplength{foldmarkhpos}{5mm} 60 | 61 | % Reference line 62 | \@setplength{refvpos}{94mm} 63 | \@setplength{refaftervskip}{8.46mm} 64 | 65 | % Signature 66 | \let\raggedsignature\raggedright 67 | 68 | 69 | % Custom Letter Head ---------------------------------------------------------- 70 | \setkomavar{firsthead}{% 71 | \parbox{\useplength{firstheadwidth}}{% 72 | \raggedleft% 73 | \ifkomavarempty{fromname}{}{{\fontsize{24pt}{24pt}\bfseries\color[gray]{0.33}\usekomavar{fromname}}\\\vspace{2mm}} 74 | {% 75 | \fontsize{10pt}{12pt}\selectfont\color[gray]{0.33}% 76 | \ifkomavarempty{fromaddress}{}{{\def\\{,\nobreakspace\@ogobble}\usekomavar{fromaddress}}~\Letter\\}% 77 | \ifkomavarempty{fromemail}{}{\usekomavar{fromemail}~\MVAt\\}% 78 | \ifkomavarempty{fromphone}{}{\usekomavar{fromphone}~\Telefon\\}% 79 | \ifkomavarempty{fromurl}{}{\usekomavar{fromurl}~\Mundus\\}% 80 | } 81 | } 82 | } 83 | 84 | 85 | 86 | % Hack to provide sections ---------------------------------------------------- 87 | % The class scrlttr2 has no sections! 88 | % Inspired by deprecated `sections.lco` https://komascript.de/sections.lco 89 | % Markus Kohm now recommends to use class `scrartcl` with package `scrletter`. 90 | % Example: https://tex.stackexchange.com/a/464722 91 | 92 | % Counter 93 | \newcounter{section} 94 | \renewcommand*{\thesection}{\@arabic\c@section} 95 | \newcommand*\sectionmarkformat{\thesection\autodot\enskip} 96 | \newcounter{subsection}[section] 97 | \renewcommand*{\thesubsection}{\thesection.\@arabic\c@subsection} 98 | \newcommand*\subsectionmarkformat{\thesubsection\autodot\enskip} 99 | \newcounter{subsubsection}[subsection] 100 | \renewcommand*{\thesubsubsection}{\thesubsection.\@arabic\c@subsubsection} 101 | \setcounter{secnumdepth}{3} 102 | 103 | % Sections 104 | % \@startsection{name}{level}{indent}{beforeskip}{afterskip}{style} 105 | % beforeskip and afterskip are parskip + given length 106 | \newcommand\section{\@startsection{section}{1}{\z@}% 107 | {-3.25ex\@plus -1ex \@minus -0.2ex}% 108 | {0.5ex \@plus .1ex \@minus .1ex}% 109 | {\normalcolor\sffamily\bfseries\normalsize}} 110 | \newcommand\subsection{\@startsection{subsection}{2}{\z@}% 111 | {-1.5ex \@plus -0.1ex \@minus -0.1ex}% 112 | {1sp}% smallest possible length almost zero => results in one parskip 113 | {\normalcolor\sffamily\bfseries\normalsize}} 114 | \newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% 115 | {-1.0ex \@plus -0.1ex \@minus -0.1ex}% 116 | {0.1ex}% 117 | {\normalcolor\sffamily\bfseries\normalsize}} 118 | 119 | % hack to get rid of parskip after subsubsection line 120 | % https://tex.stackexchange.com/a/324346/218581 121 | \let\origsubsubsection\subsubsection 122 | \renewcommand\subsubsection[2][\relax]{% 123 | \ifx\relax#1\origsubsubsection{#2}\else\origsubsubsection[#1]{#2}\fi% 124 | \vspace{-\parskip}} 125 | 126 | % Alternatives: 127 | % https://tex.stackexchange.com/a/318005/218581 128 | % not chosen because of version dependency and dependency on another package 129 | % 1) runin 130 | % KOMA-Script >= 3.26 (on CTAN since 2019-01-04) provides option runin to 131 | % \DeclareSectionCommand etc. allowing for negative length in afterskip 132 | % 2) xpatch 133 | % \usepackage{xpatch} 134 | % \xapptocmd\sectionlinesformat{\vspace*{-\parskip}}{}{\PatchFailed} 135 | -------------------------------------------------------------------------------- /R/komaletter.R: -------------------------------------------------------------------------------- 1 | #' KOMA-Script LaTeX Letter Format 2 | #' 3 | #' A format for LaTeX letters via R Markdown using the KOMA-Script class 4 | #' 'scrlttr2'. It provides layouts for many different window envelope types 5 | #' (German, US, French, Japanese, ...) and lets you define customized layouts. 6 | #' 7 | #' @param ... Additional arguments to [rmarkdown::pdf_document()] 8 | #' @param keep_tex A boolean toggle to select whether intermediate 9 | #' LaTeX files are to be kept, defaults to `FALSE` 10 | #' 11 | #' @return R Markdown output to pass to [rmarkdown::render()] 12 | #' 13 | #' @examples 14 | #' \dontrun{ 15 | #' rmarkdown::draft("my_letter.Rmd", template="pdf", package="komaletter") 16 | #' rmarkdown::render("my_letter.Rmd") 17 | #' } 18 | #' 19 | #' @details # Letter features 20 | #' 21 | #' Various aspects of the letter can be customized via the following 22 | #' variables in the R Markdown document metadata (aka YAML header). 23 | #' 24 | #' Although it rarely makes sense to write a letter without sender and recipient, 25 | #' a komaletter can be constructed by merely specifying the output format. 26 | #' All other variables are optional. 27 | #' 28 | #' 29 | #' Most commonly used variables: 30 | #' 31 | #' **Variable** | **Description** 32 | #' ---------------- | ------------------------------------------------------------ 33 | #' author | Writer of the letter. 34 | #' return-address | Address of the sender; takes a list for a multi-line address. 35 | #' address | Name and address of the recipient; takes a list. 36 | #' date | Custom date; if not specified, current date will be inserted. 37 | #' subject | Subject line. 38 | #' opening | Text for the salutation. 39 | #' closing | Text for the complementary close, like: Best regards. 40 | #' signature | Text (e.g. your name) or an image of your signature with `"\\includegraphics{sig.png}"`. 41 | #' signature-before | Adjust vertical space between closing and signature by specifying a length such as `2mm` or `"0.5\\baselineskip"`. 42 | #' 43 | #' 44 | #' All variables understood by `rmarkdown`'s `pdf_document` format may be used 45 | #' in addition to the `komaletter` variables defined in the following table 46 | #' to further customize your letter. For modifications of the layout please 47 | #' refer to the vignette "Introduction to komaletter". 48 | #' 49 | #' Further variables defined by komaletter: 50 | #' 51 | #' **Variable** | **Description** 52 | #' ------------ | ---------------------------------------------------------------- 53 | #' lco | Letter Class Option File. Either name of a standard KOMA-Script LCO (e.g. DIN, SN, ) or path to custom LCO. If not specified, the `maintainersDelight.lco` will be used. 54 | #' lang | Language code according to [BCP 47](https://www.rfc-editor.org/rfc/rfc5646.html) (e.g. `en` or `en-GB`). 55 | #' papersize | Size of paper eg. `a4`, `letter`. 56 | #' return-phone | Phone number of sender used in letter head. 57 | #' return-email | Email address of sender used in letter head. 58 | #' return-url | Website of sender used in letter head. 59 | #' return-short | Shorter version of return address only used in window (see vignette `letter_example4`). 60 | #' place | Sender’s place used near date. 61 | #' yourref | Addressee’s reference as part of reference line. 62 | #' yourmail | Date of addressee’s referenced mail as part of reference line. 63 | #' myref | Sender’s reference as part of reference line. 64 | #' customer | Customer number as part of reference line. 65 | #' invoice | Invoice number as part of reference line. 66 | #' cc | Recipients to be carbon-copied; can take a list. 67 | #' encl | List of enclosures. 68 | #' ps | Text to be added at the end of the letter as a postscript. 69 | #' inline-links | If true, do standard inline hyperlinks rather than footnotes (styling is author's job, cf. vignette `letter_example2`). 70 | #' komaoption | Specify further KOMA options; takes a list (see [KOMA-Script documentation](https://komascript.de/~mkohm/scrguien.pdf)). 71 | #' parskip | Defines how to mark new paragraphs, e.g. full, half, off (see [KOMA-Script documentation](https://komascript.de/~mkohm/scrguien.pdf)). 72 | #' 73 | #' 74 | #' The source of the example letter vignettes show several of these options in use. 75 | #' 76 | #' 77 | #' @references 78 | #' JJ Allaire, Yihui Xie, Jonathan McPherson et al. (2020). rmarkdown: 79 | #' Dynamic Documents for R. R package version 2.6. 80 | #' 81 | #' 82 | #' Aaron Wolen and Andrew Dunning (2017). pandoc-letter. GitHub Repository. 83 | #' 84 | #' 85 | #' Markus Kohm (2020). KOMA-Script: A versatile LaTeX \eqn{2_\epsilon}{2\epsilon} bundle. 86 | #' 87 | #' 88 | #' @export 89 | komaletter <- function(..., keep_tex=FALSE){ 90 | 91 | template <- system.file("rmarkdown", "templates", "pdf", "resources", 92 | "template.tex", package="komaletter") 93 | default_lco <- system.file("rmarkdown", "templates", "pdf", "resources", 94 | "maintainersDelight.lco", package="komaletter") 95 | default_lco <- sub("\\.[^.]*$", "", default_lco) 96 | 97 | base <- inherit_pdf_document(..., template=template, keep_tex=keep_tex, 98 | md_extensions=c("-autolink_bare_uris"), 99 | pandoc_args=c(paste0("--variable=lco_default:", 100 | default_lco))) 101 | 102 | base$knitr$opts_chunk$prompt <- FALSE 103 | base$knitr$opts_chunk$comment <- '# ' 104 | base$knitr$opts_chunk$highlight <- TRUE 105 | 106 | return(base) 107 | } 108 | 109 | 110 | # Call rmarkdown::pdf_document and mark the return value as inheriting pdf_document 111 | inherit_pdf_document <- function(...){ 112 | fmt <- rmarkdown::pdf_document(...) 113 | fmt$inherits <- "pdf_document" 114 | 115 | return(fmt) 116 | } 117 | -------------------------------------------------------------------------------- /vignettes/intro.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction to komaletter" 3 | author: "Robert Nuske" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Introduction to komaletter} 8 | %\VignetteKeywords{komaletter,vignette} 9 | %\VignettePackage{komaletter} 10 | %\VignetteEngine{knitr::rmarkdown} 11 | %\VignetteEncoding{UTF-8} 12 | --- 13 | 14 | ```{r setup, include = FALSE} 15 | knitr::opts_chunk$set( 16 | collapse = TRUE, 17 | comment = "#>" 18 | ) 19 | ``` 20 | 21 | Letters are fairly standardized products and as such lend themselves to be 22 | written in Markdown. This package is inspired by [linl](https://cran.r-project.org/package=linl) 23 | but it wraps the very configurable KOMA-Script class *scrlttr2* instead of the 24 | standard LaTeX document class *letter*. 25 | 26 | *komaletter* strives to turn a simple R Markdown document together with a layout 27 | definition into a beautiful letter (PDF). Layout definitions can be one of 28 | KOMA-Script's standard styles, the package default style or a user defined style. For more details refer to the section [Letter Layouts](#letter-layouts). 29 | 30 | Various aspects of the letter can be determined via variables in the R Markdown 31 | document metadata (aka YAML header), see [Letter settings](#letter-settings). 32 | 33 | Pay attention to the [printing](#about-printing) of your letter. A shrunk or scaled-down document might (besides a ruined layout) may result in parts of the address not being visible. 34 | 35 | 36 | ## Usage 37 | An easy way to start a new *komaletter* is to ask for the skeleton document 38 | in RStudio via *New File > R Markdown > From Template > komaletter* or 39 | `rmarkdown::draft("myletter.Rmd", template="pdf", package="komaletter")`. 40 | To turn the markown in a beautiful PDF use the Knit Button in RStudio or `rmarkdown::render("myletter.Rmd")`. 41 | 42 | The skeleton creates a very simple letter as a starting point for your own 43 | writing. Several formatting defaults for font, fontsize, indentation are in use. 44 | The following figure shows the complete source on the left and the rendered PDF 45 | on the right. 46 | 47 | ![](../man/figures/skeleton.png) 48 | 49 | 50 | ## Letter Settings 51 | Various aspects of the letter can be customized via the following 52 | variables in the R Markdown document metadata (aka YAML header). 53 | 54 | Although it rarely makes sense to write a letter without sender and recipient, 55 | a komaletter can be constructed by merely specifying the output format. 56 | All other variables are optional. 57 | 58 | 59 | Variable | Description 60 | ---------------- | ------------------------------------------------------------ 61 | author | Writer of the letter 62 | return-address | Address of the sender; takes a list for a multi-line address. 63 | address | Name and address of the recipient; takes a list. 64 | date | Custom date; if not specified, current date will be inserted. 65 | subject | Subject line. 66 | opening | Text for the salutation. 67 | closing | Text for the complementary close, like: Best regards. 68 | signature | Text (e.g. your name) or an image of your signature with `"\\includegraphics{sig.png}"`. 69 | signature-before | Adjust vertical space between closing and signature by specifying a length such as `2mm` or `"0.5\\baselineskip"`. 70 | 71 | Table: Most commonly used variables. 72 | 73 | 74 | All variables understood by `rmarkdown`'s `pdf_document` format may be used 75 | in addition to the `komaletter` variables defined in the following table 76 | to further customize your letter. These variables do not change the placement 77 | of elements of the letter (address, letter head, text). For those aspects 78 | refer to [Letter Layouts](#letter-layouts). 79 | 80 | Variable | Description 81 | ------------ | ---------------------------------------------------------------- 82 | lco | Letter Class Option File (cf. [Letter Layouts](#letter-layouts)). 83 | lang | Language code according to [BCP 47](https://www.rfc-editor.org/rfc/rfc5646.html) (e.g. `en` or `en-GB`). 84 | papersize | Size of paper eg. `a4`, `letter`. 85 | return-phone | Phone number of sender used in letter head. 86 | return-email | Email address of sender used in letter head. 87 | return-url | Website of sender used in letter head. 88 | return-short | Shorter version of return address only used in window (see vignette `letter_example4`). 89 | place | Sender’s place used near date. 90 | yourref | Addressee’s reference as part of reference line. 91 | yourmail | Date of addressee’s referenced mail as part of reference line. 92 | myref | Sender’s reference as part of reference line. 93 | customer | Customer number as part of reference line. 94 | invoice | Invoice number as part of reference line. 95 | cc | Recipients to be carbon-copied; can take a list. 96 | encl | List of enclosures. 97 | ps | Text to be added at the end of the letter as a postscript. 98 | inline-links | If true, do standard inline hyperlinks rather than footnotes (styling is author's job, cf. vignette `letter_example2`). 99 | komaoption | Specify further KOMA options; takes a list (see [KOMA-Script documentation](https://komascript.de/~mkohm/scrguien.pdf)). 100 | parskip | Defines how to mark new paragraphs, e.g. full, half, off (see [KOMA-Script documentation](https://komascript.de/~mkohm/scrguien.pdf)). 101 | 102 | Table: Further komaletter variables. 103 | 104 | ## Letter Layouts 105 | The layout of letters is defined in so-called **Letter Class Option** files. 106 | KOMA-Script provides a number of standard styles (see following table). 107 | The package comes with a default style defined in *maintainersDelight.lco*. 108 | Users may as well define there own layout. 109 | 110 | Styles can be selected via the variable `lco` in the YAML header of the 111 | rmarkdown document. Provide either the name of one of the standard styles 112 | listed below or the path to a self defined style without file extension. 113 | If LaTeX can not find the **lco** file, it uses KOMA-Script's default: **DIN**. 114 | Common errors besides typos are paths *with* extension, underscores in paths 115 | mangeled by pandoc. 116 | 117 | Custom *lco's* may be constructed either based on one of the standard lco-files 118 | or by defining all aspects such as position of the recpients address, 119 | foldmarks etc.. For a comprehensive description refer to the 120 | [KOMA-Script Guide](https://komascript.de/~mkohm/scrguien.pdf). 121 | 122 | 123 | 124 | Country | Standard | Window Envelope | Paper Size | lco 125 | ------------- | ------------ | ---------------- | ---------- | ---------------- 126 | Germany | DIN 676 | DIN lang, C4, C5 | A4 | DIN, DINmtext 127 | France | NF Z 11-001 | DL | A4 | NF 128 | Switzerland | SN 010 130 | DIN lang, C4, C5 | A4 | SN, SNleft 129 | United States | | commercial #9 | Letter | UScommercial9, UScommercial9DW 130 | Japan | | Chou/You 3 & 4 | A4 | NipponEL, ... 131 | 132 | Table: Some of KOMA-Script's standard LCOs. 133 | 134 | 135 | ## Internationalisation 136 | It is easy to write letters in non English languages. The necessary *language* and *layout* settings can be achieved with the YAML variables `lang` and `lco`. `komaletter` passes these on to the LaTeX template and the nicely internationalized KOMA-Script letter class. 137 | 138 | The language can be specified via the two letter code such as `en`, `de`, `fr`, `es`. Or if you want to be more precise by adding a country `en-US` for American English or `de-CH` for Swiss German. KOMA-Script then generates e.g. the date according to language and country conventions. 139 | 140 | Beware that you need additional LaTeX language packages if you choose a non English language. Make sure you have the necessary LaTeX language packs, _i.e._ `texlive-lang-german` for a German letter (`lang: de`) which should be present if you write LaTeX Documents in that language. 141 | 142 | A letter layout fitting for the local window envelope style can be select using the YAML variable `lco`. The various letter layouts are discussed in the previous section. A french letter layout for the window envelope style *DL* would be selected via `lco: NF`. 143 | 144 | 145 | ## About Printing 146 | Some PDF viewers do not realize that the document already has a blank margin and scale or 'fit to page' for printing. This generally results in smaller fonts, overly large margins, broken layout and most importantly a misplaced address. In the worst case, parts of the address are not visible in the window of the envelope. 147 | 148 | komaletter's default layout signals the PDF viewer to print the document at its actual size. Unfortunately, not many PDF viewers heed this hint. 149 | 150 | Thus, before printing the document, you should check that the document is not shrunk or 'fit to page'. **The document must be printed at its actual size / 100%** so that the positions of the elements are correct (not possible in Okular < 1.7 (Applications 19.04), e.g. part of Kubuntu 18.04). 151 | 152 | 153 | ## Hints 154 | * The default papersize of KOMA-Script class *scrlttr2* is DIN A4. If you want to create an US style letter eg. using `lco: UScommercial9`, remember to set the papersize to `letter`. 155 | 156 | * If your `return-address` is very long, it might not fit on the one line backaddress in the address window. The letter layout coming with the package komaletter tries hard to craft a pretty two-line version. The other option is using the YAML parameter `return-short` to provide an alternative one line address only used in the address window. `return-short` can be a list such as `return-address` or just one line of text. See also the vignette `letter_example4`. 157 | 158 | * Since the figure environment is not defined in the classes `letter` and `scrlltr2`, pandoc has to be told not to wrap the image into `\begin{figure}...\end{figure}`. Which can be achieved by ending the line with a backslash: 159 | ``` 160 | ![Alt text](image.png)\ 161 | ``` 162 | If you just want a regular inline image, just make sure it is not the only thing in the paragraph. One way to do this is to insert a nonbreaking space after the image: 163 | ``` 164 | ![This image won't be a figure](/url/of/image.png)\ 165 | ``` 166 | -------------------------------------------------------------------------------- /vignettes/parameterized_letter.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Parameterized Letters for Mass Mailings" 3 | author: "Robert Nuske" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Parameterized Letters for Mass Mailings} 8 | %\VignetteKeywords{komaletter, vignette, parameter, mass mailing, mail merge} 9 | %\VignettePackage{komaletter} 10 | %\VignetteEngine{knitr::rmarkdown} 11 | %\VignetteEncoding{UTF-8} 12 | --- 13 | 14 | ```{r setup, include = FALSE} 15 | knitr::opts_chunk$set( 16 | collapse = TRUE, 17 | comment = "#>" 18 | ) 19 | ``` 20 | 21 | 22 | Mail merge is just a variant of R Markdown's parameterized reports using `komaletter`. The process is similar to mail merge in traditional word processing applications: 23 | 24 | * write template letter with placeholders (parameters) 25 | * compile data on recipients 26 | * combine template letter and recipients data 27 | 28 | 29 | ## TLDR: Example 30 | 31 | Template letter (saved as `template_letter.Rmd`): 32 | 33 | ```{r eval=FALSE} 34 | --- 35 | author: Max Mustermann 36 | return-address: [Musterstr. 12, 34567 Musterstadt] 37 | signature: Max 38 | 39 | params: 40 | name: DefaultNickname 41 | address: "[Default Name, 123 Default St, Default Town]" 42 | gift: DefaultGift 43 | 44 | output: komaletter::komaletter 45 | --- 46 | --- 47 | address: `r params$address` 48 | opening: `r paste0('Dear ', params$name, ',')` 49 | closing: "Yours truly," 50 | --- 51 | 52 | thank you very much for the beautiful `r params$gift`. It was a pleasure to have you. 53 | ``` 54 | 55 | 56 | Collect data about recipients in data.frame `recipients`: 57 | 58 | ```{r eval=FALSE} 59 | recipients <- data.frame(name=c("Bob", "Megan", "Alex"), 60 | gift=c("painting", "candlestick", "book"), 61 | address=c("[Robert Pitts, 5543 Aliquet St, Fort Dodge GA 20783]", 62 | "[Megan Smith, 4156 Tincidunt Ave, Green Bay IN 19759]", 63 | "[Alexander Fitzgerald, 869 Laurel Ave, St Paul MN 55104]"), 64 | stringsAsFactors=FALSE) 65 | ``` 66 | 67 | 68 | Combine template letter with recipients' data and create lots of PDFs: 69 | 70 | ```{r eval=FALSE} 71 | for(i in 1:nrow(recipients)){ 72 | rmarkdown::render("template_letter.Rmd", 73 | params=list(name=recipients[i, "name"], 74 | gift=recipients[i, "gift"], 75 | address=recipients[i, "address"]), 76 | output_file=paste0("letter_", recipients[i, 'name'], ".pdf")) 77 | } 78 | ``` 79 | 80 | 81 | ## Basics of Mail Merge with `komaletter` 82 | To personalize letters for mass mailings, you can include one or more placeholders (parameters) in a `komaletter`. These parameters need to be declared first and then put to use later in the document. While rendering the letters, you can assign various values to the parameters. 83 | 84 | 85 | ### Declaring Parameters 86 | Parameters are declared in the YAML metadata header using the `params` field. You can specify one or more parameters each on a new line. The default values (below: John & candlestick) given during parameter declaration, will be used if a parameter is not provided during rendering. 87 | ```{r eval=FALSE} 88 | --- 89 | params: 90 | name: John 91 | gift: candlestick 92 | 93 | output: komaletter::komaletter 94 | --- 95 | ``` 96 | 97 | 98 | ### Using Parameters 99 | The declared parameters are automatically made available within the knit environment as components of the read-only list `params`. For example, the values of the above parameters can be accessed with the following R Code: 100 | ```{r eval=FALSE} 101 | params$name 102 | params$gift 103 | ``` 104 | 105 | If the value of a parameter shall be used in the YAML metadata header, the parameter must be declared previously. Since the backtick \` is a reserved character in YAML, the inline R Code snippet has to be wrapped in quotes. 106 | ```{r eval=FALSE} 107 | --- 108 | params: 109 | name: John 110 | gift: candlestick 111 | 112 | subject: "`r params$gift`" 113 | 114 | output: komaletter::komaletter 115 | --- 116 | ``` 117 | 118 | 119 | ### Setting Parameter values 120 | To set the parameter values, you can add the `params` argument to `rmarkdown::render`. If a parameter does not get a value, the default defined during parameter declaration is used (eg. `John`, `candlestick`). 121 | ```{r eval=FALSE} 122 | rmarkdown::render("example.Rmd", params=list(name="Jane")) 123 | ``` 124 | 125 | 126 | ## Challenges of Mail Merge with `komaletter` 127 | R Markdown and thus `komaletter` combines R Code, YAML and Markdown. R Markdown documents are processed by `knitr` to pure YAML and Markdown which in turn is send to pandoc for conversion to the final document type (pdf in this case). A parametrized letter has to obey the restrictions of all parts involved. 128 | 129 | The most common personalization are the address of the recipient and the salutation or opening. `komaletter` expects the address to be a YAML sequence within the YAML metadata header. YAML sequences can be written in flow or block style. Both need quotation marks to protect the square brackets or to enable the escape code `\n` during parameter declaration in the YAML metadata. 130 | 131 | ```{r eval=FALSE} 132 | --- 133 | params: 134 | # scalar: 135 | name: John Doe 136 | # flow style sequence: 137 | address_flow: "[FirstName LastName, 123 Main St, Anytown]" 138 | # block style sequence: 139 | address_block: "\n - FirstName LastName\n - 123 Main St\n - Anytown" 140 | --- 141 | ``` 142 | 143 | Since the address and the letter opening are defined in the YAML metadata. The corresponding parameters must be declared and afterwards put to use within the YAML metadata. Parameter values are accessed in R Code. In the YAML metadata header this means inline code snippets `` `r knitr::inline_expr("expression")` ``. Since backticks `` ` `` are 'reserved indicators' in YAML, the code snippet usually needs to be wrapped in quotes. 144 | 145 | ```{r eval=FALSE} 146 | --- 147 | params: 148 | name: John Doe 149 | 150 | opening: "`r paste0('Dear ', params$name, ',')`" 151 | 152 | output: komaletter::komaletter 153 | --- 154 | ``` 155 | 156 | The result of the quoted R expression `` "`r knitr::inline_expr("expression")`" `` is a value enclosed in double quotes, i.e. `"value"`, which is not harmful if the result is of R type character corresponding to a YAML scalar. YAML scalars can be enclosed in single or double quotes or not wrapped at all. But everything in quotes is a scalar to YAML. 157 | 158 | Consequently this means that expressions that are supposed to supply an address and thus a YAML sequence, must not be enclosed in quotes! Which poses a main problem since we learned above inline code snippets need to be enclosed in quotes in the main YAML metadata header. 159 | 160 | 161 | ## Solution 162 | Or rather a **hack** found as bycatch at [stackoverflow](https://stackoverflow.com/a/31862074) circumventing the issue at the moment. 163 | 164 | As explained above, the address is a YAML sequence and sequences can not be enclosed in quotes. To access the parameter in the main YAML metadata header the inline R Code snippet has to be wrapped in quotes and R expressions wrapped in quotes evaluate to a value enclosed in quotes. 165 | 166 | Mysteriously, the rule that backticks must be enclosed in quotes is not enforced in a second YAML metadata block. You can use two metadata blocks because Pandoc combines YAML metadata blocks while converting the .md file to the final document. So in a second metadata block the inline R Code snippet can be written without quotes resulting in a correctly formatted YAML sequence. 167 | 168 | ```{r eval=FALSE} 169 | --- 170 | author: Max Mustermann 171 | return-address: [Musterstr. 12, 34567 Musterstadt] 172 | signature: Max 173 | 174 | params: 175 | name: Johnny 176 | address: "[John Doe, 123 Main St, Anytown]" 177 | gift: flowers 178 | 179 | output: komaletter::komaletter 180 | --- 181 | --- 182 | address: `r params$address` 183 | opening: `r paste0('Dear ', params$name, ',')` 184 | closing: "Yours truly," 185 | --- 186 | 187 | thank you very much for the beautiful `r params$gift`. It was a pleasure to have you. 188 | ``` 189 | 190 | 191 | The template letter above can then be called with various values 192 | ```{r eval=FALSE} 193 | recipients <- data.frame(name=c("Bob", "Megan", "Alex"), 194 | gift=c("painting", "candlestick", "book"), 195 | address=c("[Robert Pitts, 5543 Aliquet St, Fort Dodge GA 20783]", 196 | "[Megan Smith, 4156 Tincidunt Ave, Green Bay IN 19759]", 197 | "[Alexander Fitzgerald, 869 Laurel Ave, St Paul MN 55104]"), 198 | stringsAsFactors=FALSE) 199 | 200 | 201 | for(i in 1:nrow(recipients)){ 202 | rmarkdown::render("template_letter.Rmd", 203 | params=list(name=recipients[i, "name"], 204 | gift=recipients[i, "gift"], 205 | address=recipients[i, "address"]), 206 | output_file=paste0("letter_", recipients[i, 'name'], ".pdf")) 207 | } 208 | 209 | ``` 210 | 211 | 212 | ## Further Information 213 | * R Markdown 214 | * [Chapter "Parametrized Reports"](https://bookdown.org/yihui/rmarkdown/parameterized-reports.html) in the book "R Markdown: The Definitive Guide" 215 | * [Lesson 6 "Parameters"](https://rmarkdown.rstudio.com/lesson-6.html) in "Get Started"-Course on RStudio's R Markdown website 216 | 217 | * YAML 218 | * [YAML Reference card](https://yaml.org/refcard.html) (Scalar indicators, Escape codes, Misc. Indicators for reserved indicators) 219 | * [YAML Specification](https://yaml.org/spec/current.html) (Syntax, Indicator Characters: reserved characters, Escape Sequences, Scalar Styles, Sequence Styles) 220 | * [YAML block sequence](https://yaml.org/spec/current.html#id2543032) 221 | * [YAML flow sequence](https://yaml.org/spec/current.html#id2542413) 222 | 223 | 224 | ## Hints 225 | Since parameters are evaluated roughly speaking during document knitting (conversion from `.Rmd` to `.md`), it is helpful to look at the intermediate `.md` files to hunt down issues in parameterized letters. 226 | 227 | Since `komaletter` is based on rmarkdown's output format `pdf_document`, you can use the argument `keep_md` to obtain the intermediary `.md` file (`rmarkdown >= 1.14`). Previously one had to resort to `rmarkdown::render(..., clean=FALSE)` to cause the intermediate `.md` files to remain available. 228 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/pdf/resources/template.tex: -------------------------------------------------------------------------------- 1 | \documentclass[version=last,$if(fontsize)$$fontsize$$else$12pt$endif$,{"$if(lco)$$lco$$else$$lco_default$$endif$"},$if(lang)$$babel-lang$,$endif$$if(address)$$else$addrfield=false,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{scrlttr2} 2 | 3 | % For Debuging the Layout ---------------------------------------------------- 4 | % \LoadLetterOption{visualize} 5 | % \showfields{head,address,location,refline,foot} 6 | % \setkomafont{field}{\color{blue}} 7 | % ----------------------------------------------------------------------------- 8 | 9 | $if(fontfamily)$ 10 | \usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} 11 | $else$ 12 | \usepackage{mathpazo} 13 | $endif$ 14 | $if(linestretch)$ 15 | \usepackage{setspace} 16 | \setstretch{$linestretch$} 17 | $endif$ 18 | \usepackage{amssymb,amsmath} 19 | \usepackage{ifxetex,ifluatex} 20 | \usepackage{fixltx2e} % provides \textsubscript 21 | \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex 22 | \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} 23 | \usepackage[utf8]{inputenc} 24 | $if(euro)$ 25 | \usepackage{eurosym} 26 | $endif$ 27 | \else % if luatex or xelatex 28 | \ifxetex 29 | \usepackage{mathspec} 30 | \else 31 | \usepackage{fontspec} 32 | \fi 33 | \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase} 34 | $for(fontfamilies)$ 35 | \newfontfamily{$fontfamilies.name$}[$fontfamilies.options$]{$fontfamilies.font$} 36 | $endfor$ 37 | $if(euro)$ 38 | \newcommand{\euro}{€} 39 | $endif$ 40 | $if(mainfont)$ 41 | \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} 42 | $endif$ 43 | $if(sansfont)$ 44 | \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} 45 | $endif$ 46 | $if(monofont)$ 47 | \setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$endif$]{$monofont$} 48 | $endif$ 49 | $if(mathfont)$ 50 | \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} 51 | $endif$ 52 | $if(CJKmainfont)$ 53 | \usepackage{xeCJK} 54 | \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} 55 | $endif$ 56 | \fi 57 | % use upquote if available, for straight quotes in verbatim environments 58 | \IfFileExists{upquote.sty}{\usepackage{upquote}}{} 59 | % use microtype if available 60 | \IfFileExists{microtype.sty}{% 61 | \usepackage{microtype} 62 | \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts 63 | }{} 64 | % \usepackage[margin=1in]{geometry} interfers with the areaset in my lco_default 65 | %\usepackage[$if(geometry)$$for(geometry)$$geometry$$sep$,$endfor$$else$margin=1in$endif$]{geometry} 66 | \usepackage[unicode=true,pdfversion=1.6]{hyperref} % PrintScaling needs 1.6 67 | $if(colorlinks)$ 68 | \PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref 69 | $endif$ 70 | \hypersetup{ 71 | $if(title-meta)$ 72 | pdftitle={$title-meta$}, 73 | $endif$ 74 | $if(author-meta)$ 75 | pdfauthor={$author-meta$}, 76 | $endif$ 77 | $if(keywords)$ 78 | pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$}, 79 | $endif$ 80 | $if(colorlinks)$ 81 | colorlinks=true, 82 | linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$, 83 | citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$, 84 | urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$, 85 | $else$ 86 | pdfborder={0 0 0}, 87 | $endif$ 88 | breaklinks=true, 89 | pdfprintscaling=None} % signal the PDF viewer "no auto scale", PDF >= 1.6 90 | \urlstyle{same} % don't use monospace font for urls 91 | 92 | % removed polyglossia according to jgm/pandoc@f4d2c9e 93 | $if(lang)$ 94 | \usepackage[$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} 95 | % get rid of language-specific shorthands (see pandoc #6817): 96 | \let\LanguageShortHands\languageshorthands 97 | \def\languageshorthands#1{} 98 | $endif$ 99 | 100 | % citations 101 | $if(natbib)$ 102 | \usepackage[$natbiboptions$]{natbib} 103 | \bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} 104 | $endif$ 105 | $if(biblatex)$ 106 | \usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex} 107 | $for(bibliography)$ 108 | \addbibresource{$bibliography$} 109 | $endfor$ 110 | $endif$ 111 | $if(nocite-ids)$ 112 | \nocite{$for(nocite-ids)$$it$$sep$, $endfor$} 113 | $endif$ 114 | 115 | $if(csl-refs)$ 116 | \newlength{\cslhangindent} 117 | \setlength{\cslhangindent}{1.5em} 118 | \newlength{\csllabelwidth} 119 | \setlength{\csllabelwidth}{3em} 120 | \newlength{\cslentryspacingunit} % times entry-spacing 121 | \setlength{\cslentryspacingunit}{\parskip} 122 | % For Pandoc 2.8 to 2.11 123 | \newenvironment{cslreferences}% 124 | {$if(csl-hanging-indent)$\setlength{\parindent}{0pt}% 125 | \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces$endif$}% 126 | {\par} 127 | % For pandoc 2.11+ using new --citeproc 128 | \newenvironment{CSLReferences}[2] % #1 hanging-ident, #2 entry spacing 129 | {% don't indent paragraphs 130 | \setlength{\parindent}{0pt} 131 | % turn on hanging indent if param 1 is 1 132 | \ifodd #1 133 | \let\oldpar\par 134 | \def\par{\hangindent=\cslhangindent\oldpar} 135 | \fi 136 | % set entry spacing 137 | \setlength{\parskip}{#2\cslentryspacingunit} 138 | }% 139 | {} 140 | \usepackage{calc} 141 | \newcommand{\CSLBlock}[1]{#1\hfill\break} 142 | \newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}} 143 | \newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break} 144 | \newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1} 145 | $endif$ 146 | 147 | $if(listings)$ 148 | \usepackage{listings} 149 | $endif$ 150 | $if(lhs)$ 151 | \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} 152 | $endif$ 153 | $if(highlighting-macros)$ 154 | $highlighting-macros$ 155 | $endif$ 156 | $if(verbatim-in-note)$ 157 | \usepackage{fancyvrb} 158 | \VerbatimFootnotes % allows verbatim text in footnotes 159 | $endif$ 160 | $if(tables)$ 161 | \usepackage{longtable,booktabs,array} 162 | $if(multirow)$ 163 | \usepackage{multirow} 164 | $endif$ 165 | \usepackage{calc} % for calculating minipage widths 166 | % Correct order of tables after \paragraph or \subparagraph 167 | \usepackage{etoolbox} 168 | \makeatletter 169 | \patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} 170 | \makeatother 171 | % Allow footnotes in longtable head/foot 172 | \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} 173 | \makesavenoteenv{longtable} 174 | $endif$ 175 | $if(graphics)$ 176 | \usepackage{graphicx} 177 | % grffile has become a legacy package: https://ctan.org/pkg/grffile 178 | \IfFileExists{grffile.sty}{% 179 | \usepackage{grffile} 180 | }{} 181 | \makeatletter 182 | \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} 183 | \def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} 184 | % set default figure placement to htbp 185 | \def\fps@figure{htbp} 186 | \makeatother 187 | % Scale images if necessary, so that they will not overflow the page 188 | % margins by default, and it is still possible to overwrite the defaults 189 | % using explicit options in \includegraphics[width, height, ...]{} 190 | \setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} 191 | $endif$ 192 | $if(inline-links)$ 193 | % let links be hotlinks in text (styling is writer's job) 194 | $else$ 195 | % make links footnotes instead of hotlinks (default) 196 | \renewcommand{\href}[2]{#2\footnote{\url{#1}}} 197 | $endif$ 198 | $if(strikeout)$ 199 | \usepackage[normalem]{ulem} 200 | % avoid problems with \sout in headers with hyperref: 201 | \pdfstringdefDisableCommands{\renewcommand{\sout}{}} 202 | $endif$ 203 | $if(parskip)$ 204 | \KOMAoptions{parskip=$parskip$} 205 | $endif$ 206 | \setlength{\emergencystretch}{3em} % prevent overfull lines 207 | \providecommand{\tightlist}{% 208 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 209 | $if(numbersections)$ 210 | \setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} 211 | $else$ 212 | \setcounter{secnumdepth}{0} 213 | $endif$ 214 | $if(subparagraph)$ 215 | $else$ 216 | % Redefines (sub)paragraphs to behave more like sections 217 | \ifx\paragraph\undefined\else 218 | \let\oldparagraph\paragraph 219 | \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} 220 | \fi 221 | \ifx\subparagraph\undefined\else 222 | \let\oldsubparagraph\subparagraph 223 | \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} 224 | \fi 225 | $endif$ 226 | $if(dir)$ 227 | \ifxetex 228 | % load bidi as late as possible as it modifies e.g. graphicx 229 | $if(latex-dir-rtl)$ 230 | \usepackage[RTLdocument]{bidi} 231 | $else$ 232 | \usepackage{bidi} 233 | $endif$ 234 | \fi 235 | \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex 236 | \TeXXeTstate=1 237 | \newcommand{\RL}[1]{\beginR #1\endR} 238 | \newcommand{\LR}[1]{\beginL #1\endL} 239 | \newenvironment{RTL}{\beginR}{\endR} 240 | \newenvironment{LTR}{\beginL}{\endL} 241 | \fi 242 | $endif$ 243 | 244 | \makeatletter 245 | $if(signature)$ 246 | \usepackage{graphicx} 247 | % grffile has become a legacy package: https://ctan.org/pkg/grffile 248 | \IfFileExists{grffile.sty}{% 249 | \usepackage{grffile} 250 | }{} 251 | % set default figure placement to htbp 252 | \def\fps@figure{htbp} 253 | $if(signature-before)$ 254 | \@setplength{sigbeforevskip}{$signature-before$} 255 | $endif$ 256 | \setkomavar{signature}{$signature$} 257 | $else$ 258 | % suppress signature 259 | $if(signature-before)$ 260 | \@setplength{sigbeforevskip}{$signature-before$} 261 | $else$ 262 | \@setplength{sigbeforevskip}{0mm} 263 | $endif$ 264 | \setkomavar{signature}{} 265 | $endif$ 266 | \makeatother 267 | 268 | $for(header-includes)$ 269 | $header-includes$ 270 | $endfor$ 271 | 272 | $if(komaoption)$ 273 | \KOMAoptions{$for(komaoption)$$komaoption$$sep$,$endfor$} 274 | $endif$ 275 | 276 | $if(return-phone)$ 277 | \KOMAoptions{fromphone=true} 278 | \setkomavar{fromphone}{$return-phone$} 279 | $endif$ 280 | $if(return-email)$ 281 | \KOMAoptions{fromemail=true} 282 | \setkomavar{fromemail}{$return-email$} 283 | $endif$ 284 | $if(return-url)$ 285 | \KOMAoptions{fromurl=true} 286 | \setkomavar{fromurl}{$return-url$} 287 | $endif$ 288 | 289 | $if(date)$\setkomavar{date}{$date$}$endif$ 290 | $if(yourref)$\setkomavar{yourref}{$yourref$}$endif$ 291 | $if(yourmail)$\setkomavar{yourmail}{$yourmail$}$endif$ 292 | $if(myref)$\setkomavar{myref}{$myref$}$endif$ 293 | $if(customer)$\setkomavar{customer}{$customer$}$endif$ 294 | $if(invoice)$\setkomavar{invoice}{$invoice$}$endif$ 295 | $if(place)$\setkomavar{place}{$place$}$endif$ 296 | $if(subject)$\setkomavar{subject}{$subject$}$endif$ 297 | $if(author)$\setkomavar{fromname}{$author$}$endif$ 298 | $if(return-address)$ 299 | \setkomavar{fromaddress}{$for(return-address)$$return-address$$sep$\\$endfor$} 300 | $endif$ 301 | 302 | $if(return-short)$ 303 | \setkomavar{backaddress}{$for(return-short)$$return-short$$sep$\\$endfor$} 304 | $endif$ 305 | 306 | \begin{document} 307 | 308 | $for(include-before)$ 309 | $include-before$ 310 | 311 | $endfor$ 312 | $if(toc)$ 313 | { 314 | $if(colorlinks)$ 315 | \hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$} 316 | $endif$ 317 | \setcounter{tocdepth}{$toc-depth$} 318 | \tableofcontents 319 | } 320 | $endif$ 321 | 322 | \begin{letter}{$for(address)$$address$$sep$\\$endfor$} 323 | $if(opening)$\opening{$opening$}$else$\opening{}$endif$ 324 | 325 | $body$ 326 | 327 | $if(closing)$\closing{$closing$}$endif$ 328 | $if(encl)$\encl{$for(encl)$$encl$$sep$\\$endfor$}$endif$ 329 | $if(cc)$\cc{$for(cc)$$cc$$sep$\\$endfor$}$endif$ 330 | $if(ps)$\ps{$ps$}$endif$ 331 | 332 | \end{letter} 333 | 334 | $if(natbib)$ 335 | $if(bibliography)$ 336 | $if(biblio-title)$ 337 | $if(book-class)$ 338 | \renewcommand\bibname{$biblio-title$} 339 | $else$ 340 | \renewcommand\refname{$biblio-title$} 341 | $endif$ 342 | $endif$ 343 | \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} 344 | 345 | $endif$ 346 | $endif$ 347 | $if(biblatex)$ 348 | \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ 349 | 350 | $endif$ 351 | $for(include-after)$ 352 | $include-after$ 353 | 354 | $endfor$ 355 | \end{document} 356 | -------------------------------------------------------------------------------- /man/figures/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xmlkomaletter 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | --------------------------------------------------------------------------------