Guide
Check a document with lint
Find text that overflows its column, squeezed columns, missing glyphs, lonely headings, split rows and markup in text fields, as text or JSON.
On this page
brevier lint renders a template and checks the pages, not the source. It
lists every problem with its page and the line of the generated HTML that
caused it. It writes no PDF.
brevier lint rechnung.html --data rechnung.json --debug-dir out/rechnung.html
page 1 table column "Stk" squeezed below its minimum width (10.0 < 15.0 mm) → out/rechnung.debug.html:9
→ 1 problem. exit code 1
debug file: out/rechnung.debug.html (holds the document's data)Exit code 0 means no problems. Exit code 1 means at least one problem. Run it in your build to stop a bad document before a customer sees it. All options are on the CLI reference.
What lint reports
| Kind | Meaning |
|---|---|
overflow |
Text wider than its table column or its box. The message names the column header, the first 20 characters and both widths in mm. |
table |
A table column narrower than its declared minimum width. See below. |
glyph |
A character that the font does not draw, or that a fallback font draws instead of the font you asked for. |
orphan |
A heading alone at the bottom of a page. A heading at the end of the last page is not reported. |
split |
A table row broken across two pages. The message names the row number and the pages. |
hyphens |
More than 3 hyphenated lines in a row, or one before a page break. |
data |
A value in your data that does not fit its field type: markup or a line break in a text field. See Check the data. |
Check the data
A problem can be in the data and not in the layout. A text field removes line
breaks and prints markup as plain text: the value Zeile 1<br/>Zeile 2 prints
the characters <br/> on the page. Lint finds this before the PDF is made.
The check runs when you pass --data and a schema is found. The schema is
<name>.schema.json next to the template, or the one you name with --schema.
A field has the type text when its schema has "x-brevier-type": "text" or no
x-brevier-type. A field that the schema does not list counts as text.
{
"type": "object",
"properties": {
"rechnung": {
"type": "object",
"properties": {
"nummer": { "type": "string" },
"bemerkung": { "type": "string", "x-brevier-type": "text" },
"lieferhinweis": { "type": "string", "x-brevier-type": "multiline" }
}
}
}
}Take a rechnung.json with 5 records. Three records have <br/> in
bemerkung, and one has a line break in it. All 5 records have a line break in
lieferhinweis.
brevier lint rechnung.html --data rechnung.jsonrechnung.html
document data rechnung.bemerkung contains markup (3 of 5 records): suggest `multiline` or `rich`
document data rechnung.bemerkung contains newlines (1 of 5 records): suggest `multiline`
→ 2 problems. exit code 1
debug file: rechnung.debug.html (holds the document's data)- Lint reports one line for each field and problem, with the number of records
that have it. The path starts at the root of the record, so
kunde.nameandlieferant.nameare two fields with two types. lieferhinweisis not reported: amultilinefield keeps line breaks. Arichfield keeps markup.- Markup means an HTML tag such as
<br/>,<b>or</p>. The textPreis < 5 und > 3is not markup. - The messages never contain the values of your data.
- The
datafindings have no page and no line: the cause is in the data, not in the generated HTML.
The fix is in the schema or in the data. Declare multiline or rich for a
field that should keep line breaks or markup, or clean the value in your
application. See Field types.
| Situation | What lint does |
|---|---|
--data and a schema |
Checks the data. |
--data and no schema |
Skips the data check and prints No schema for rechnung.html: data checks skipped on standard error. This is not a problem: the exit code does not change. |
--schema false |
Skips the data check. |
| A schema file that is missing or not valid JSON | Stops with an error and exit code 1. |
Read the output as JSON
--format json prints an array with one object for each problem and [] when
there is none. Each object has the keys page, kind, message, file and
line. Use it to feed another tool.
brevier lint rechnung.html --data rechnung.json --format json[
{
"page": null,
"kind": "data",
"message": "rechnung.bemerkung contains markup (3 of 5 records): suggest `multiline` or `rich`",
"file": null,
"line": null
},
{
"page": null,
"kind": "data",
"message": "rechnung.bemerkung contains newlines (1 of 5 records): suggest `multiline`",
"file": null,
"line": null
}
]page, file and line are null for a problem that has no place in the
generated HTML.
Declare a minimum column width
A table column has no minimum width by default, so lint never reports a
squeezed column on its own. You declare the minimum on the <col> of the
column, with the attribute data-min-width:
<table>
<col style="width: 40mm">
<col style="width: 25mm" data-min-width="20mm">
<tr><th>Position</th><th>Menge</th></tr>
</table>CSS min-width does not work on a column, so Brevier reads this attribute
instead.
- The value is a number followed by
mm:20mmor22.5mm. Any other value is ignored. - Lint compares the width of the column on the page with the minimum. It reports the column when it is narrower by more than 0.3 mm.
- A column without the attribute is never reported.
- The attribute changes nothing in the PDF. Only
brevier lintreads it.
Run lint in CI
Run brevier lint in your build pipeline to catch layout problems before
generating PDFs for customers.
Licence key and network
Like brevier pdf, brevier lint needs a licence key in the environment
variable BREVIER_LICENCE_KEY. Store your licence key in your CI platform's
secrets settings.
Linting needs no network access. It runs completely offline.
Debug HTML warning
brevier lint writes a debug HTML file (such as rechnung.debug.html or in
--debug-dir) to show line numbers for reported problems. This file contains
the document's rendered data.
Do not save or publish the debug HTML file as a public CI artifact, because it contains the document's data.
GitHub Actions
This workflow installs Brevier with pip and lints a template on every push
and pull request. Add your licence key as the repository secret
BREVIER_LICENCE_KEY.
name: lint templates
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install Pango and brevier
run: |
sudo apt-get update -qq
sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0
pip install brevier
- name: Lint the templates
env:
BREVIER_LICENCE_KEY: ${{ secrets.BREVIER_LICENCE_KEY }}
run: brevier lint templates/rechnung.html --data templates/rechnung.jsonA finding gives exit code 1, so the job fails and the pull request shows it.