Arabic, Hebrew and Hindi
Arabic, Hebrew and Hindi with Latin words and numbers inside them, a table laid out right to left, and six scripts justified with kashidas, the stretched joins of Arabic-style writing. Inter falls back to Noto fonts for the scripts it lacks, and the text is shaped with HarfBuzz (Tagua.Shaping.HarfBuzz).
Standards: PDF/A-2b · PDF/UA-1, checked with veraPDF on every change. Download the PDF.

What it shows
Section titled “What it shows”- The Unicode Bidirectional Algorithm, with embedded numbers
- A right-to-left table
- Font fallback from Inter to Noto
- Kashida justification: Arabic, Syriac, N’Ko, Mandaic, Adlam, Mongolian
- Each block tagged with its language (PDF/UA-1)
The template
Section titled “The template”# yaml-language-server: $schema=../schema/template.schema.json# Right-to-left and complex scripts: Arabic, Hebrew and Hindi with embedded Latin words and numbers,# a right-to-left table, Arabic, Syriac, N'Ko, Mandaic, Adlam and Mongolian justified with kashidas, and# PDF/A-2b + PDF/UA-1. Inter falls back to Noto fonts for# the scripts it lacks. Rendered with the HarfBuzz shaper (Tagua.Shaping.HarfBuzz).version: 1title: Multilingual textculture: en-GB
document: author: Acme Ltd compliance: [pdf-a-2b, pdf-ua-1]
page: size: A4 margins: 22mm
fonts: Inter: regular: fonts/Inter-Regular.ttf bold: fonts/Inter-Bold.ttf fallback: [NotoArabic, NotoHebrew, NotoDevanagari, NotoSyriac, NotoNKo, NotoMandaic, NotoAdlam, NotoMongolian] NotoArabic: { regular: fonts/NotoSansArabic-Regular.ttf } NotoHebrew: { regular: fonts/NotoSansHebrew-Regular.ttf } NotoDevanagari: { regular: fonts/NotoSansDevanagari-Regular.ttf } NotoSyriac: { regular: fonts/NotoSansSyriac-Regular.ttf } NotoNKo: { regular: fonts/NotoSansNKo-Regular.ttf } NotoMandaic: { regular: fonts/NotoSansMandaic-Regular.ttf } NotoAdlam: { regular: fonts/NotoSansAdlam-Regular.ttf } NotoMongolian: { regular: fonts/NotoSansMongolian-Regular.ttf }
styles: default: { font: Inter, fontSize: 11pt, lineHeight: 1.6, color: "#1F1F1F" } label: { fontSize: 8.5pt, color: "#6B6B6B", padding: 10pt 0 2pt 0 } th: { fontWeight: bold, borderBottom: "0.75pt solid #1F1F1F", padding: 0 0 3pt 0 } total: { fontWeight: bold, borderTop: "0.75pt solid #1F1F1F", padding: 3pt 0 0 0 }
data: notice: fields: { Arabic: string, Hebrew: string, Hindi: string, Syriac: string, Nko: string, Mandaic: string, Adlam: string, Mongolian: string, Invoice: string } items: fields: { Item: string, Quantity: int32, Price: decimal }
body: dataset: notice
detail: - content: - { type: text, value: "Right-to-left and complex scripts", fontSize: 18pt, fontWeight: bold, tag: h1 } - type: text value: >- Each paragraph takes its direction from its first strong character. Arabic and Hindi are shaped with HarfBuzz; words and numbers in other scripts keep their own order.
- content: - { type: text, value: "Arabic, justified with kashidas", style: label } - layout: row # right to left: the narrow paragraph sits at the right textDirection: rtl content: - { type: text, value: "{Arabic}", language: ar, align: justify, width: 330pt } - content: - { type: text, value: "Hebrew", style: label } - { type: text, value: "{Hebrew}", language: he } - { type: text, value: "Hindi", style: label } - { type: text, value: "{Hindi}", language: hi } - { type: text, value: "Syriac and N'Ko, justified with kashidas (tatweel and lajanyalan)", style: label } - layout: row textDirection: rtl gap: 24pt content: - { type: text, value: "{Syriac}", language: aii, align: justify, width: 1fr } - { type: text, value: "{Nko}", language: nqo, align: justify, width: 1fr } - content: - { type: text, value: "Mandaic, Adlam and Mongolian (set horizontally), justified with kashidas", style: label } - layout: row textDirection: rtl gap: 24pt content: - { type: text, value: "{Mandaic}", language: myz, align: justify, width: 1fr } - { type: text, value: "{Adlam}", language: ff-Adlm, align: justify, width: 1fr } # Mongolian runs left to right: undo the row's inherited rtl for its words. - { type: text, value: "{Mongolian}", language: mn-Mong, align: justify, width: 1fr, textDirection: auto }
- padding: 16pt 0 0 0 content: - { type: text, value: "A right-to-left table (textDirection: rtl)", style: label } - type: table dataset: items textDirection: rtl language: ar headerStyle: th columns: - { header: الصنف, value: "{Item}", width: 1fr } - { header: الكمية, value: "{Quantity}", width: 60pt, align: end } - { header: السعر, value: "{Price:N2}", width: 80pt, align: end } footer: - style: total cells: - { value: المجموع, span: 2, isHeader: true } - { value: "{Sum(Quantity * Price):N2}", align: end } - { type: text, value: "Invoice {Invoice} · فاتورة {Invoice} · חשבונית {Invoice}", style: label }
pageFooter: - content: - { type: text, value: "Page {PageNumber} of {TotalPages}", align: right, color: "#6B6B6B", fontSize: 8pt }Render it yourself
Section titled “Render it yourself”Save the template, put the fonts it names next to it (Inter and the Noto fonts are free, under the SIL Open Font License), and run:
tagua render multilingual.report.yaml --openWithout a data file, tagua render makes up sample rows from the field types; see Preview as you edit.