529 lines
19 KiB
Markdown
529 lines
19 KiB
Markdown
# Business Suite
|
|||
|
|
|
||
|
|
Business Suite provides shared LaTeX templates for reports, letters and Beamer presentations. A single company package defines the corporate identity—colours, fonts, logo and contact details—and all templates use that configuration.
|
||
|
|
|
||
|
|
The suite contains no company-specific colour values, font names or asset paths. Corporate identities therefore remain private while the reusable templates can be published and tested independently.
|
||
|
|
|
||
|
|
## Components
|
||
|
|
|
||
|
|
| Component | Purpose |
|
||
|
|
| --- | --- |
|
||
|
|
| `business-identity.sty` | Defines colours, fonts, logos and shared commands |
|
||
|
|
| `business-suite.sty` | Formats reports and other standard LaTeX documents |
|
||
|
|
| `business-brief.cls` | Provides business letters based on `g-brief2` |
|
||
|
|
| `business-beamer.sty` | Provides the shared Beamer presentation design |
|
||
|
|
| `md2pdf.py` | Converts Markdown to a branded PDF through Pandoc and XeLaTeX |
|
||
|
|
|
||
|
|
## Requirements
|
||
|
|
|
||
|
|
- A LaTeX installation with XeLaTeX
|
||
|
|
- Pandoc and Python 3 for Markdown conversion
|
||
|
|
- Inkscape when a document contains SVG images
|
||
|
|
|
||
|
|
Company-specific fonts and packages must also be available to XeLaTeX.
|
||
|
|
|
||
|
|
## Quick Start
|
||
|
|
|
||
|
|
### Install the Suite
|
||
|
|
|
||
|
|
Link the suite and converter into the local TeX and executable trees. Symbolic links keep the installation aligned with the working copy.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
mkdir -p ~/texmf/tex/latex ~/bin
|
||
|
|
ln -s ~/git/mrw/business-suite/texmf/tex/latex/business-suite \
|
||
|
|
~/texmf/tex/latex/business-suite
|
||
|
|
ln -s ~/git/mrw/business-suite/bin/md2pdf.py ~/bin/md2pdf.py
|
||
|
|
```
|
||
|
|
|
||
|
|
Install a company identity in the same way:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ln -s ~/git/nordwind/latex ~/texmf/tex/latex/nordwind
|
||
|
|
```
|
||
|
|
|
||
|
|
For builds that must not depend on the local installation, set `TEXINPUTS` to the source tree. The npm scripts in this repository do this automatically.
|
||
|
|
|
||
|
|
### Create a Company Identity
|
||
|
|
|
||
|
|
Each company has one package, such as `nordwind.sty`. It defines the palette, maps colours to semantic roles, configures the fonts and registers the logo before loading the document template.
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\NeedsTeXFormat{LaTeX2e}
|
||
|
|
\ProvidesPackage{nordwind}[2026/09/21 Nordwind AG corporate identity]
|
||
|
|
|
||
|
|
\RequirePackage{business-identity}
|
||
|
|
|
||
|
|
\definecolor{nordwind-deep}{HTML}{14425C}
|
||
|
|
\definecolor{nordwind-sea}{HTML}{3E8EA8}
|
||
|
|
|
||
|
|
\businesscolours{
|
||
|
|
brand = nordwind-deep,
|
||
|
|
title = nordwind-deep,
|
||
|
|
titlemeta = nordwind-deep!60,
|
||
|
|
text = black,
|
||
|
|
running-strong = nordwind-deep,
|
||
|
|
running-quiet = nordwind-deep!55,
|
||
|
|
folio = nordwind-deep!55,
|
||
|
|
caption = nordwind-deep!70,
|
||
|
|
rowrule = nordwind-deep!25,
|
||
|
|
heading-bg = nordwind-deep,
|
||
|
|
heading-fg = white,
|
||
|
|
border = nordwind-sea,
|
||
|
|
thick-border = nordwind-deep,
|
||
|
|
black-border = black,
|
||
|
|
}
|
||
|
|
|
||
|
|
\setmainfont{TeX Gyre Pagella}
|
||
|
|
\setsansfont{TeX Gyre Heros}
|
||
|
|
\setmonofont{TeX Gyre Cursor}[Scale=MatchLowercase]
|
||
|
|
|
||
|
|
\businessfonts{
|
||
|
|
default = rm,
|
||
|
|
symbols = DejaVu Sans,
|
||
|
|
smallcaps = false,
|
||
|
|
}
|
||
|
|
|
||
|
|
\businessidentity{
|
||
|
|
name = Nordwind,
|
||
|
|
url = https\://nordwind.example,
|
||
|
|
address = https\://nordwind.example,
|
||
|
|
lockup = icon+text,
|
||
|
|
icon = nordwind-icon,
|
||
|
|
}
|
||
|
|
|
||
|
|
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{business-suite}}
|
||
|
|
\ProcessOptions\relax
|
||
|
|
\RequirePackage{business-suite}
|
||
|
|
|
||
|
|
\endinput
|
||
|
|
```
|
||
|
|
|
||
|
|
### Create a Document
|
||
|
|
|
||
|
|
Load the company package instead of the generic template:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\documentclass[a4paper,10pt]{article}
|
||
|
|
\usepackage{nordwind}
|
||
|
|
|
||
|
|
\title{Annual Report}
|
||
|
|
\author{Erika Muster}
|
||
|
|
\date{\today}
|
||
|
|
|
||
|
|
\begin{document}
|
||
|
|
\maketitle
|
||
|
|
|
||
|
|
\section{Current Position}
|
||
|
|
Dolor sit amet.
|
||
|
|
|
||
|
|
\end{document}
|
||
|
|
```
|
||
|
|
|
||
|
|
The template automatically applies the corporate logo, page header, footer, title block, heading rules, table widths, image sizing, PDF outline and PDF metadata.
|
||
|
|
|
||
|
|
### Convert Markdown
|
||
|
|
|
||
|
|
```bash
|
||
|
|
md2pdf.py --identity nordwind report.md
|
||
|
|
```
|
||
|
|
|
||
|
|
The equivalent npm command is:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm run md2pdf -- --identity nordwind report.md
|
||
|
|
```
|
||
|
|
|
||
|
|
To provide a company-specific command, add a wrapper to the `PATH`:
|
||
|
|
|
||
|
|
```sh
|
||
|
|
#!/bin/sh
|
||
|
|
exec md2pdf.py --identity nordwind "$@"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Corporate Identity
|
||
|
|
|
||
|
|
### Colour Roles
|
||
|
|
|
||
|
|
Company packages define concrete colours and assign them to semantic roles. Templates use only these roles.
|
||
|
|
|
||
|
|
| Role | Usage |
|
||
|
|
| --- | --- |
|
||
|
|
| `brand` | Logo and primary accents |
|
||
|
|
| `text` | Body text |
|
||
|
|
| `title` | Document title |
|
||
|
|
| `titlemeta` | Author and date |
|
||
|
|
| `running-strong` | First line of the running header |
|
||
|
|
| `running-quiet` | Second line of the running header |
|
||
|
|
| `folio` | Page number |
|
||
|
|
| `caption` | Image captions |
|
||
|
|
| `rowrule` | Table row separators |
|
||
|
|
| `success`, `fail` | Status marks |
|
||
|
|
| `heading-bg`, `heading-fg` | Heading bands and presentation bars |
|
||
|
|
| `border`, `thick-border`, `black-border` | Document frames |
|
||
|
|
|
||
|
|
A role can reference a palette colour directly or use an `xcolor` mixture such as `nordwind-deep!50!black`. The `success` and `fail` roles default to green and red and do not have to be part of the company palette.
|
||
|
|
|
||
|
|
### Font Settings
|
||
|
|
|
||
|
|
The company package loads and configures `fontspec`; `\businessfonts` tells the templates how to use the configured families.
|
||
|
|
|
||
|
|
| Key | Meaning |
|
||
|
|
| --- | --- |
|
||
|
|
| `default` | Default document family: `rm` or `sf` |
|
||
|
|
| `emphasis` | Face used for emphasis; defaults to bold when omitted |
|
||
|
|
| `symbols` | Fallback family for missing symbols |
|
||
|
|
| `smallcaps` | Set to `false` if the selected font has no small capitals |
|
||
|
|
| `microtype` | Set to `false` to disable microtypography |
|
||
|
|
| `protrusion` | Set to `true` to allow punctuation to extend into the margin |
|
||
|
|
|
||
|
|
The font encoding remains associated with the selected family. This prevents a class that preselects a family using T1 encoding from silently falling back to Computer Modern.
|
||
|
|
|
||
|
|
### Logo Configuration
|
||
|
|
|
||
|
|
The identity can reference an image file or a drawing command:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\businessidentity{logo = company-logo}
|
||
|
|
\businessidentity{icon code = \companydrawing}
|
||
|
|
```
|
||
|
|
|
||
|
|
Image filenames omit the extension. The suite checks PDF, EPS, PNG and JPEG in that order. Convert SVG logos before the build.
|
||
|
|
|
||
|
|
A drawing command receives the requested height and must produce a box of exactly that height. TikZ drawings should freeze their bounding box with `\pgfresetboundingbox` and an explicit `\path[use as bounding box]`. The selected logo colour is available as `\businesslogocolour`.
|
||
|
|
|
||
|
|
The `lockup` setting defines the logo structure:
|
||
|
|
|
||
|
|
- `banner`: the asset already contains the icon and company name.
|
||
|
|
- `icon+text`: the suite places the company name beside the icon.
|
||
|
|
|
||
|
|
With a `banner` lockup, the tagline appears below the complete banner and aligns with its right edge.
|
||
|
|
|
||
|
|
### Tagline
|
||
|
|
|
||
|
|
Add a second line below the company name with `tagline`:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\businessidentity{
|
||
|
|
name = Nordwind,
|
||
|
|
tagline = Vernunft und Freiheit,
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The following optional keys change the default appearance:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\businessidentity{
|
||
|
|
name face = {\bfseries},
|
||
|
|
tagline face = {\mdseries},
|
||
|
|
tagline color = business-running-quiet,
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The name is 80% of the requested logo height. The tagline is set to the size at which it is exactly as wide as the name above it, so both lines share one left edge and one right edge whatever the sentence says. The gap between them is 20% of the name size and `taglinegap` changes it.
|
||
|
|
|
||
|
|
The icon takes the height of the text block beside it and keeps the proportions of its own drawing. A mark with a height of its own matches the text at one type size and at no other.
|
||
|
|
|
||
|
|
Each measured size has a key that overrides it:
|
||
|
|
|
||
|
|
| Key | Overrides |
|
||
|
|
| --- | --- |
|
||
|
|
| `taglinefactor` | the tagline size, as a share of the name instead of its width |
|
||
|
|
| `iconheight` | the icon height, instead of the height of the text block |
|
||
|
|
| `iconwidth` | the icon width; the height follows from the drawing |
|
||
|
|
|
||
|
|
Never give both icon sizes at once: two fixed sizes distort the mark. A width also reaches a drawn icon, not only an image file. The suite sets the icon once, measures its width and scales the height by the ratio.
|
||
|
|
|
||
|
|
Templates request the tagline where sufficient space is available. Logos in running text remain on one line unless `tagline` is explicitly requested.
|
||
|
|
|
||
|
|
## Shared Commands
|
||
|
|
|
||
|
|
### Logos
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\logo
|
||
|
|
\logo[height=2cm]
|
||
|
|
\logo[address]
|
||
|
|
\logo[icon]
|
||
|
|
\logo[text]
|
||
|
|
\logo[nolink]
|
||
|
|
\logo[color=business-text]
|
||
|
|
\logo[tagline]
|
||
|
|
\logo[tagline,address]
|
||
|
|
```
|
||
|
|
|
||
|
|
Use `\businesslogo` where another package owns `\logo`; Beamer, for example, uses `\logo` to set the presentation logo.
|
||
|
|
|
||
|
|
By default, logos are 1.25 em high in running text and 2 em high in template headers. The company name is 80% of the logo height. Gaps beside the icon and above the address are 10% of the logo height. Each value can be overridden.
|
||
|
|
|
||
|
|
The address line is scaled to the exact width of the logo or lockup above it. The icon is vertically centred beside the name while the name retains the surrounding text baseline.
|
||
|
|
|
||
|
|
### Status Marks
|
||
|
|
|
||
|
|
`\success` and `\fail` render white status symbols on green and red backgrounds. The Unicode characters `✅`, `❌`, `✓`, `✗`, `✔` and `✘` map to the same marks, which allows Markdown sources to use them directly.
|
||
|
|
|
||
|
|
Other common symbols—including arrows, information signs, warnings, stars and checkboxes—use the active text font when available and the configured symbol family otherwise. Unsupported characters are omitted without adding a gap or log message.
|
||
|
|
|
||
|
|
### Images
|
||
|
|
|
||
|
|
Use `\businessgraphic` for template-controlled image sizing:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\businessgraphic{diagram}
|
||
|
|
\businessgraphic[width=4cm]{diagram}
|
||
|
|
```
|
||
|
|
|
||
|
|
Default sizing depends on orientation:
|
||
|
|
|
||
|
|
- Portrait images use up to the full line width and half the text height.
|
||
|
|
- Landscape images use up to the full line width and the free height remaining on the page.
|
||
|
|
- Images retain their aspect ratio and are centred.
|
||
|
|
- If an image would leave no more than 25% of a page empty, it moves to the next page. Otherwise, it is reduced to fit the current page.
|
||
|
|
- Vector graphics may use the full calculated size. Raster images are enlarged by at most a factor of two.
|
||
|
|
|
||
|
|
| Option | Default | Meaning |
|
||
|
|
| --- | ---: | --- |
|
||
|
|
| `portraitwidth` | `1` | Maximum share of the line width for portrait images |
|
||
|
|
| `portraitheight` | `0.5` | Maximum share of the text height for portrait images |
|
||
|
|
| `landscapewidth` | `1` | Maximum share of the line width for landscape images |
|
||
|
|
| `landscapeheight` | `1` | Maximum share of the remaining page height |
|
||
|
|
| `pictureempty` | `0.25` | Maximum empty page share before an image is reduced |
|
||
|
|
| `picturezoom` | `2` | Maximum enlargement factor for raster images |
|
||
|
|
|
||
|
|
Markdown conversion applies these rules automatically.
|
||
|
|
|
||
|
|
### Footer Content
|
||
|
|
|
||
|
|
The outer footer shows the current page and total page count. Add optional content to the inner footer in the preamble:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\businessfootleft{\includegraphics[height=2em]{product}}
|
||
|
|
```
|
||
|
|
|
||
|
|
The footer may contain a product logo, classification or series name. Its reserved height is measured from the rendered content. Define it before `\begin{document}` because page geometry cannot be recalculated afterwards.
|
||
|
|
|
||
|
|
### Columns
|
||
|
|
|
||
|
|
`businesscolumns` creates equal-width columns. Their widths follow from the current line width, and the gap between columns equals one body-text line.
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\begin{businesscolumns}[3]
|
||
|
|
\businesscell{First}
|
||
|
|
\businesscell{Second}
|
||
|
|
\businesscell{Third}
|
||
|
|
\end{businesscolumns}
|
||
|
|
```
|
||
|
|
|
||
|
|
Use `\businessuse{<name>}` to include a reusable block from the TeX tree, such as a sender block or terms page.
|
||
|
|
|
||
|
|
### Tables
|
||
|
|
|
||
|
|
Use standard LaTeX table environments with the shared table commands:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\begin{tabular}{lr}
|
||
|
|
\toprule
|
||
|
|
\businesstablehead{Figure} & \businesstablehead{Value} \\
|
||
|
|
\midrule
|
||
|
|
Turnover & 4.2 million \\ \businessrowrule
|
||
|
|
People & 31 \\
|
||
|
|
\bottomrule
|
||
|
|
\end{tabular}
|
||
|
|
```
|
||
|
|
|
||
|
|
- `\businesstablehead{...}` formats a header cell.
|
||
|
|
- `\businessrowrule` draws the separator between rows.
|
||
|
|
|
||
|
|
Keep an introductory sentence with the following table or list using:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\businessleadin[2]
|
||
|
|
The annual figures:
|
||
|
|
\businesstogether
|
||
|
|
```
|
||
|
|
|
||
|
|
The optional argument specifies the number of lines occupied by the introduction. The default is six. The Markdown converter inserts both commands where required.
|
||
|
|
|
||
|
|
## Document Layout
|
||
|
|
|
||
|
|
### Header and Footer
|
||
|
|
|
||
|
|
The first page shows the corporate logo and address. Subsequent pages use two running-header lines and display the current and total page count in the footer.
|
||
|
|
|
||
|
|
The suite measures the actual header and footer content. It leaves one body-text line between the header and text area and the same distance between the text area and footer. The `headsep` option changes the upper distance; the lower distance is derived from it.
|
||
|
|
|
||
|
|
### Page Composition
|
||
|
|
|
||
|
|
The first text line begins at the upper edge of the text block. Paragraph spacing may stretch by up to half a line so that pages end on a consistent baseline. The `pagestretch` option controls this flexibility.
|
||
|
|
|
||
|
|
Headings remain attached to their following content. Tables and images use the current line width and available page height instead of fixed dimensions from a particular company design.
|
||
|
|
|
||
|
|
## Business Letters
|
||
|
|
|
||
|
|
`business-brief.cls` extends `g-brief2` with the corporate identity and shared logo handling. Create a company-specific class:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\NeedsTeXFormat{LaTeX2e}
|
||
|
|
\ProvidesClass{nordwind-brief}[2026/09/21]
|
||
|
|
|
||
|
|
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{business-brief}}
|
||
|
|
\ProcessOptions\relax
|
||
|
|
\LoadClass{business-brief}
|
||
|
|
\RequirePackage[plain]{nordwind}
|
||
|
|
|
||
|
|
\RetourAdresse{Nordwind~AG~-~Hafenstrasse~4~-~8000~Zürich}
|
||
|
|
\NameZeileA{Nordwind AG}
|
||
|
|
\NameZeileB{Hafenstrasse 4}
|
||
|
|
\NameZeileC{CH~--~8000 Zürich}
|
||
|
|
\InternetZeileA{https\://nordwind.example}
|
||
|
|
\InternetZeileB{post\@nordwind.example}
|
||
|
|
\BankZeileA{CH00 0000 0000 0000 0000 0}
|
||
|
|
\Gruss{Mit freundlichen Grüssen}{2em}
|
||
|
|
|
||
|
|
\endinput
|
||
|
|
```
|
||
|
|
|
||
|
|
The class preserves the existing `g-brief2` field names. It adds:
|
||
|
|
|
||
|
|
| Command | Purpose |
|
||
|
|
| --- | --- |
|
||
|
|
| `\Unterschriftsbild{<file>}{<name>}` | Inserts a printed signature instead of reserving space for a handwritten one |
|
||
|
|
| `\businessnowindow` | Removes the envelope window, folding marks and return line, then reduces the address field to the current address height |
|
||
|
|
| `\businesslogoheight` | Sets the header logo height, capped at the available 20 mm |
|
||
|
|
|
||
|
|
The first page places the logo and address above the sender block. Later pages place the page number and date on the left and the logo on the right.
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\documentclass[english]{nordwind-brief}
|
||
|
|
|
||
|
|
\Datum{\today}
|
||
|
|
\Adresse{Ms\\Erika Muster\\Beispielweg 7\\8001 Zurich}
|
||
|
|
\Betreff{Our offer for the harbour}
|
||
|
|
\Anrede{Dear Ms Muster}
|
||
|
|
\Unterschrift{Hans Beispiel\\Managing Director}
|
||
|
|
|
||
|
|
\begin{document}
|
||
|
|
\begin{g-brief}
|
||
|
|
We are pleased to send you our offer.
|
||
|
|
\end{g-brief}
|
||
|
|
\end{document}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Presentations
|
||
|
|
|
||
|
|
Create a two-line company theme:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
% beamerthemenordwind.sty
|
||
|
|
\RequirePackage[plain]{nordwind}
|
||
|
|
\RequirePackage{business-beamer}
|
||
|
|
```
|
||
|
|
|
||
|
|
Load it from a presentation with `\usetheme{nordwind}`:
|
||
|
|
|
||
|
|
```latex
|
||
|
|
\documentclass[12pt]{beamer}
|
||
|
|
\usetheme{nordwind}
|
||
|
|
|
||
|
|
\title{The Harbour}
|
||
|
|
\author{Hans Beispiel}
|
||
|
|
\date{\today}
|
||
|
|
|
||
|
|
\begin{document}
|
||
|
|
\begin{frame}[plain]
|
||
|
|
\titlepage
|
||
|
|
\end{frame}
|
||
|
|
|
||
|
|
\section{Current Position}
|
||
|
|
|
||
|
|
\begin{frame}
|
||
|
|
\frametitle{Project Status}
|
||
|
|
\begin{itemize}
|
||
|
|
\item \success{} Permission granted
|
||
|
|
\item \fail{} Funding open
|
||
|
|
\end{itemize}
|
||
|
|
\end{frame}
|
||
|
|
\end{document}
|
||
|
|
```
|
||
|
|
|
||
|
|
The theme uses Beamer's `sidebar` outer theme. Configure it with Beamer's standard `width`, `height`, `left`, `right`, `hideothersubsections` and `hideallsubsections` options.
|
||
|
|
|
||
|
|
Business Suite adds:
|
||
|
|
|
||
|
|
| Option | Effect |
|
||
|
|
| --- | --- |
|
||
|
|
| `titleprefix` | Adds content before every frame title |
|
||
|
|
| `canvas=brand` | Uses the brand colour as the slide background |
|
||
|
|
| `nosectionframe` | Disables the opening frame for each section |
|
||
|
|
|
||
|
|
## Markdown Converter
|
||
|
|
|
||
|
|
`md2pdf.py` passes the selected identity and document template to Pandoc, then builds the generated LaTeX with XeLaTeX.
|
||
|
|
|
||
|
|
| Option | Default | Effect |
|
||
|
|
| --- | --- | --- |
|
||
|
|
| `--identity <name>` | Required | Selects the company identity package |
|
||
|
|
| `--out-dir <dir>` | Source directory | Sets the PDF output directory |
|
||
|
|
| `--lang <tag>` | `auto` | Controls hyphenation; `auto` detects the language unless the document defines `lang:` |
|
||
|
|
| `--paper <name>` | `a4paper` | Sets the paper format |
|
||
|
|
| `--fontsize <pt>` | `10pt` | Sets the document font size |
|
||
|
|
| `--toc` | Off | Adds a table of contents |
|
||
|
|
| `--highlight` | Off | Enables Pandoc syntax highlighting in code blocks |
|
||
|
|
| `--keep-tex` | Off | Retains the generated LaTeX and build files |
|
||
|
|
|
||
|
|
Use `$E = mc^2$` for inline formulas and `$$...$$` for display formulas. The converter joins multi-line formulas before Pandoc parses them and reports this correction. This avoids Markdown interpreting a line containing only `=` as a level-one heading underline.
|
||
|
|
|
||
|
|
## Development
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm run build # Build all examples
|
||
|
|
npm test # Run all measurement tests
|
||
|
|
npm run clean # Remove generated files
|
||
|
|
```
|
||
|
|
|
||
|
|
The examples in `examples/` use `nordwind.sty`, a fictional company identity built from portable TeX Gyre fonts. The dedicated name avoids collisions with existing TeX Live packages.
|
||
|
|
|
||
|
|
Additional project documentation:
|
||
|
|
|
||
|
|
- [Tests](TESTS.md)
|
||
|
|
- [Features](FEATURES.md)
|
||
|
|
- [Open Tasks](TODO.md)
|
||
|
|
|
||
|
|
## Design Decisions
|
||
|
|
|
||
|
|
### No Company Data
|
||
|
|
|
||
|
|
Reusable templates contain no company-specific colour values, font names or asset paths. Tests scan all template sources and fail when they find such values.
|
||
|
|
|
||
|
|
### Measure Actual Content
|
||
|
|
|
||
|
|
The suite calculates logo height, address width, header and footer space, table-column widths and the space required by connected blocks from the rendered content. Fixed values derived from one font, paper format or company identity do not remain correct for another.
|
||
|
|
|
||
|
|
### Probe Document
|
||
|
|
|
||
|
|
The Pandoc table filter runs before LaTeX exists and therefore cannot directly inspect `\linewidth`. The converter builds a probe document with the selected company identity, then reads `\linewidth` and the width of a reference line from that document. This prevents table widths from depending on constants copied from another identity.
|
||
|
|
|
||
|
|
### Single Definition
|
||
|
|
|
||
|
|
Each company value has one authoritative definition in its identity package. The document, letter and presentation templates consume that package instead of copying its values. Tests therefore verify that templates contain no company-specific values, rather than checking whether duplicated values still match.
|
||
|
|
|
||
|
|
Shared table commands such as `\businessrowrule` and `\businesstablehead` belong to the identity layer because tables can appear in documents, letters and presentations. Loading an identity with the `plain` option retains these shared commands but omits document geometry and page styles.
|
||
|
|
|
||
|
|
### Document Language
|
||
|
|
|
||
|
|
The template does not set the document language. When Babel is loaded, Hyperref obtains the language from Babel. Setting it again would produce an `Option 'pdflang' has already been used` warning. Tests verify the resulting language in the document's XMP metadata.
|
||
|
|
|
||
|
|
### Native Beamer Sidebar
|
||
|
|
|
||
|
|
The presentation template uses Beamer's maintained `sidebar` outer theme instead of carrying a private copy.
|
||
|
|
|
||
|
|
### Letter Address Field
|
||
|
|
|
||
|
|
Window-envelope letters retain the physical 63 mm address field. With `\businessnowindow`, the field shrinks to the height required by the current recipient address and makes the remaining space available to the letter body.
|
||
|
|
|
||
|
|
## Licence
|
||
|
|
|
||
|
|
MIT, see [LICENSE](LICENSE). Use it, change it, sell what you build with it; keep the copyright notice in a copy.
|
||
|
|
|
||
|
|
Every source file of the suite carries the notice and the SPDX identifier in its first lines. A LaTeX package is installed file by file: what a company copies into its own tree is `business-suite.sty`, and the licence file does not travel with it.
|