Skip to main content
Version: Canary 🚧

Base Schema

When authoring custom locales or overriding specific fields, your provided dictionaries are evaluated against the internal base-language and base-region master schemas.

The engine utilizes a Cascading deep-merge strategy. Any key omitted in your custom locale will automatically fall back to the defaults defined in these schemas. This ensures that your invoice template always compiles safely, even if future updates introduce new fields or tax Grounds.


Language Schema (base-language)​

The language dictionary acts as the structural template for all translations. It contains exclusively linguistic strings, formatting text, and functions that assemble localized sentences.

info

All string fields within the language schema dictate the static text printed on the document. Functions within payment and global-info are used to syntactically structure dynamic values (like dates and amounts) according to regional grammar rules.

meta​

Contains core metadata about the language configuration.

KeyTypeDescription
langstrThe ISO 639-1 language code (e.g., "en", "de"). Sets the document language (text.lang), which drives hyphenation and the PDF language tag.

document​

Designations for the document types: the default titles of invoice(document-type: ..).

KeyTypeDescription
invoicestrThe title used for standard invoices (e.g., "Invoice").
credit-notestrThe title of a credit note (e.g., "Credit Note", in German "Rechnungskorrektur").
correctedstrThe title of a corrected invoice (e.g., "Corrected Invoice").
prepaymentstrThe title of a prepayment invoice (e.g., "Prepayment Invoice").
self-billedstrThe title of a self-billed invoice, the mention the law requires on it (e.g., "Self-Billing Invoice", "Gutschrift").

address​

Labels indicating the address blocks.

KeyTypeDescription
recipientstrLabel above the recipient address (e.g., "Bill To").
senderstrLabel above the sender details (e.g., "From").

reference​

Designations for header metadata.

KeyTypeDescription
tax-numberstrLabel for the sender's tax identification (e.g., "Tax ID").
invoice-numberstrLabel for the document identifier (e.g., "Invoice Number").
vat-idstrLabel for the Value Added Tax identifier (e.g., "VAT ID").
invoice-datestrLabel for the date of the invoice (e.g., "Invoice Date").
service-timestrLabel for the period of service (e.g., "Period of Service").
customer-numberstrLabel for the customer number (e.g., "Customer No.").
buyer-referencestrLabel for the buyer reference or Leitweg-ID (e.g., "Buyer Reference").
recipient-vat-idstrLabel for the buyer's VAT identifier (e.g., "Buyer VAT ID").
recipient-tax-numberstrLabel for the buyer's tax number (e.g., "Buyer Tax ID").
order-numberstrLabel for the order number (e.g., "Order No.").
order-datestrLabel for the date of the order (e.g., "Order Date").
projectstrLabel for the project (e.g., "Project").
contract-numberstrLabel for the contract number (e.g., "Contract No.").
quote-numberstrLabel for the quote number (e.g., "Quote No.").
delivery-note-numberstrLabel for the delivery note number (e.g., "Delivery Note No.").
delivery-addressstrLabel for the delivery address (e.g., "Delivery Address").
preceding-invoice-numberstrLabel for the number of the preceding invoice (e.g., "Preceding Invoice No.").
preceding-invoice-datestrLabel for the date of the preceding invoice (e.g., "Preceding Invoice Date").
due-datestrLabel for the due date (e.g., "Due Date").
payment-referencestrLabel for the payment reference (e.g., "Payment Reference").
contact-personstrLabel for the contact person (e.g., "Contact Person").
contact-phonestrLabel for the phone number of the contact (e.g., "Phone").
contact-emailstrLabel for the email address of the contact (e.g., "Email").
payeestrLabel for who receives the payment instead of the sender, e.g. a factoring company (e.g., "Payee").

line-items​

Column headers and structural labels for the line-items table.

KeyTypeDescription
positionstrColumn header for the item position index.
descriptionstrColumn header for the item name or description.
quantitystrColumn header for the item amount.
unit-pricestrColumn header for the cost per unit.
pricestrColumn header for the base price.
totalstrColumn header for the final line amount.
vatstrColumn header for the applied tax/VAT rate.
netstrSuffix or label indicating net amounts.
grossstrSuffix or label indicating gross amounts.
discountstrLabel for applied discounts.
surchargestrLabel for applied surcharges.
subtotalstrLabel indicating a running subtotal within the table.
conjunctionstrWord before the last name of a bundle description.
originstrLabel of the country of origin of an item.

summary​

Labels for the calculation footer at the end of the table.

KeyTypeDescription
sumstrLabel for the total sum before taxes.
vat-taxstrLabel for the calculated tax amount.
totalstrLabel for the final amount due.
includingstrShort label for "inclusive of".
excludingstrShort label for "exclusive of".

global-info​

Static labels and dynamic text generators placed below the table.

KeyTypeDescription
tax-statement(content, content, content) => contentSentence specifying the universal tax rate applied. Parameters map to (tax-text, rate, vat-tax).
unitstrFallback text if a uniform unit applies to all items.
quantitystrFallback text if a uniform quantity applies to all items.
datestrFallback text if a uniform service date applies to all items.

tax-exemption​

Notes on why no VAT is charged, for the tax categories that need one. When no item of such a category gives its own grounds, the note is printed below the line items and written as exemption reason (BT-120) into the e-invoice.

KeyTypeDescription
reverse-chargestrReverse charge (AE), e.g. a tax.new(category: "AE") without grounds (e.g. "Reverse charge").
intra-communitystrIntra-community supply (K), tax.intra-community() (e.g. "Tax-exempt intra-community supply").
exportstrExport outside the EU (G), tax.export() (e.g. "Tax-exempt export").
outside-scopestrNot subject to VAT (O), tax.outside-scope() (e.g. "Not subject to VAT").

units​

Designations for common units of measure.

KeyTypeDescription
piecestrLabel for a singular item (e.g., "piece").
setstrLabel for a set of items (e.g., "set").
pairstrLabel for a pair of items (e.g., "pair").
lump-sumstrLabel for a lump-sum amount (e.g., "lump sum").
hourstrLabel for hours of service (e.g., "hour").
daystrLabel for days of service (e.g., "day").
monthstrLabel for monthly billing (e.g., "month").
yearstrLabel for yearly billing (e.g., "year").
kilogramstrLabel for weight in kilograms (e.g., "kilogram").
gramstrLabel for weight in grams (e.g., "gram").
tonnestrLabel for weight in tonnes (e.g., "tonne").
metrestrLabel for length in metres (e.g., "metre").
square-metrestrLabel for area in square metres (e.g., "square metre").
millimetrestrLabel for length in millimetres (e.g., "millimetre").
centimetrestrLabel for length in centimetres (e.g., "centimetre").
kilometrestrLabel for distance in kilometres (e.g., "kilometre").
litrestrLabel for volume in litres (e.g., "litre").
cubic-metrestrLabel for volume in cubic metres (e.g., "cubic metre").

bank-details​

Labels for the payment configuration block.

KeyTypeDescription
account-holderstrLabel for the owner of the bank account.
bankstrLabel for the financial institution.
ibanstrLabel for the International Bank Account Number.
bicstrLabel for the Bank Identifier Code.
referencestrLabel for the payment reference string.

payment-means​

Texts of the payment means besides the bank details: direct-debit, card-payment and paid.

KeyTypeDescription
methodstrLabel of the payment method (e.g., "Payment method").
transfer, direct-debit, sepa-direct-debit, card, credit-card, debit-card, cash, cheque, onlinestrNames of the payment methods (e.g., "SEPA direct debit", "Cash").
mandate, creditor-id, debtor-ibanstrLabels of the details of a direct debit (e.g., "Mandate reference").
card-number, card-holderstrLabels of the details of a payment card (e.g., "Card number").
paid(content, content) => contentSentence of a paid invoice. Parameters map to (sum, date); date is none if not given.
paid-due(content, content) => contentReplaces paid when prepayments reduced the payable amount, so sum is the remaining amount that was paid.
paid-credit(content, content) => contentReplaces paid on a credit note or a self-billed invoice, whose sender paid the amount to the recipient.

payment​

Text blocks and phrasing for payment terms.

KeyTypeDescription
text(content, content) => contentGenerates the final payment instruction sentence. Parameters map to (sum, deadline).
text-due(content, content) => contentReplaces text when prepayments reduce the payable amount, so sum is the remaining amount due (e.g., "the amount due" instead of "the total amount").
text-direct-debit, text-direct-debit-due(content, content) => contenttext and text-due when the amount is collected by direct-debit.
text-card, text-card-due(content, content) => contenttext and text-due when the amount is charged to a card-payment.
cash-discount(str, str, content) => contentNote of a cash discount of the payment goal, printed after the payment sentence. Parameters map to (percent, deadline, basis); basis is none if not given.
deadline-date(content) => contentText generator for a fixed target date (e.g., [no later than #date]).
deadline-days(int) => strText generator for a relative target date (e.g., [within #str(days) days]).
deadline-soonstrText for immediate/prompt payment.
text-credit(content, content) => contentReplaces text and text-due, and the sentences of a direct debit or a payment card, on a credit note or a self-billed invoice, whose sender pays the amount to the recipient (e.g., "We will transfer the amount of ...").
deadline-soon-creditstrReplaces deadline-soon in text-credit (e.g., "promptly").

signature​

Greetings and the sign-off area.

KeyTypeDescription
closingstrThe sign-off text (e.g., "Sincerely,").

Standard legal notices.

KeyTypeDescription
vat-exemptionstrThe small business note in the invoice language. It is printed in front of the region's legal note when the language differs from the region, and alone when the region's scheme has no grounds, so it names no law.

errors​

Warning messages utilized for incorrect template usage.

KeyTypeDescription
name-missingstrError when the primary name is omitted.
address-missingstrError when the street address is omitted.
city-missingstrError when the city/postal code is omitted.
ambiguous-taxstrError thrown during ambiguous 0% tax resolution.
invalid-taxstrError thrown when an unrecognized tax rate is provided.

Region Schema (base-region)​

The region dictionary is responsible for mathematical logic and localized data representation. It dictates how dates are displayed, how currencies are formatted, and how tax structures behave.

danger

Exercise extreme caution when overriding functions in the normalize block. Returning invalid types or unhandled floats here can disrupt Forward/Backward Calculation algorithms, ultimately leading to invalid PDF generation or incorrect invoice totals.

meta​

Contains core metadata about the region configuration.

KeyTypeDescription
regionstrThe internal, lower-case identifier of the region (e.g., "de", "us").

currency​

Metadata for the primary currency used in the region. This is essential for structured data payloads like ZUGFeRD or EPC-QR codes.

KeyTypeDescription
codestrThe 3-letter ISO 4217 currency code (e.g., "EUR", "CHF").
symbolstrThe visual symbol of the currency (e.g., "€", "CHF ").
decimalsintThe standard number of subunits/decimal places for financial totals (e.g., 2).
decimals-fineintThe allowed number of decimal places for singular unit prices (usually 4).

The currency formatters (format.currency, format.currency-fine) and the rounding (normalize.money, normalize.money-fine) derive from it. If a region or an override sets the currency without these functions, they are rebuilt from it, so the printed amounts always show the currency whose code the e-invoice states (BT-5):

#import "@preview/invoice-pro:0.5.0": invoice, locale

#show: invoice.with(
// Prints "1.234,50 $" and states USD in the e-invoice
locale: locale.de-de.with((region: (currency: (code: "USD", symbol: "$")))),
)
tip

To invoice in another currency with any locale, currency on the invoice is enough: invoice(currency: "USD") sets the code, the symbol and the decimals of the currency in the same way. Override the currency of the region only for a symbol or decimals of your own.

normalize​

Functions mapping raw inputs to Normalized values.

KeyTypeDescription
moneynumber => numberRounds a numerical value to the standard decimal precision of the region's currency.
money-finenumber => numberRounds a value to a higher precision required for specific unit prices (e.g., fuel).
infer-taxratio => taxInterprets a raw tax value and maps it to a structured regional tax object containing appropriate Grounds.

format​

Functions responsible for converting data types into localized strings.

KeyTypeDescription
percent(ratio | number) => strConverts a ratio or number into a localized percentage string.
numbernumber => strFormats a number with regional thousands and decimal separators.
currencynumber => strFormats a value as a currency string with the regional symbol and standard placement.
currency-finenumber => strHigh-precision currency formatting used when unit prices require extra decimals.
date(datetime | (datetime, datetime)) => strFormats a single date or an array defining a date range into a human-readable string.
timedatetime => strFormats a time object into a localized string (e.g., 24h or AM/PM).

The regions build number, currency and currency-fine with make-formatters (from utils/format.typ), which also adds currency-formatters: a function that builds currency and currency-fine with the same number format for another currency dictionary. The locale factory uses it when an override changes the currency alone.

tax​

Contains default standard tax objects utilized by the region.

KeyTypeDescription
default-vattaxThe standard VAT/Sales Tax rate applied when no specific rate is provided.
small-enterprise-special-schemetaxThe tax of small businesses (tax-exempt-small-biz: true). Its grounds are the printed legal note and the exemption reason (BT-120) of the e-invoice. Use tax.exempt(grounds: ..) (category E) where the law exempts small businesses and tax.outside-scope(grounds: ..) (O) where they are not liable for VAT.

Example: Schema Inspection and Override​

When building your own tools or customizing a layout, you can leverage the cascading merge by specifying only the nested keys you wish to alter.

#import "@preview/invoice-pro:0.5.0": invoice, locale

#let custom-lang = (
payment: (
// Update the prompt payment phrasing
deadline-soon: "due immediately upon receipt",
)
)

#show: invoice.with(
locale: locale.build-locale(
custom-lang,
locale.region.de
)
)
note

The normalize.infer-tax function is a vital bridge. Whenever a user types a raw percentage (e.g., 19%) in their line items, this function converts it into a standardized tax object containing the correct Grounds and legal text specific to that region.