Metadata
This example shows how to add PDF metadata with rix/pdf.
The example uses the public Rix facade:
#include <rix.hpp>and accesses PDF through:
rix.pdfUse this example when you want a generated PDF to include title, author, subject, creator, and keywords.
Create the file
mkdir -p ~/rix-pdf-metadata-example
cd ~/rix-pdf-metadata-example
touch metadata.cpp2
3
Add:
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Rix PDF Metadata Example")
.set_author("Rix")
.set_subject("PDF metadata")
.set_keywords("rix,pdf,vix,cpp");
auto &page = doc.add_page();
auto y = page.heading(
page.x_left(),
page.y_top(),
"Metadata",
1);
y -= 10.0F;
page.paragraph(
page.x_left(),
y,
page.content_width(),
"This PDF includes title, author, subject, creator, and keyword metadata.");
auto saved = rix.pdf.save(doc, "rix_pdf_metadata.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "rix_pdf_metadata.pdf");
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Run it:
vix run metadata.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run metadata.cpp2
This creates:
rix_pdf_metadata.pdfWhat this example does
The example creates a PDF document:
auto doc = rix.pdf.document();It sets metadata:
doc.set_title("Rix PDF Metadata Example")
.set_author("Rix")
.set_subject("PDF metadata")
.set_keywords("rix,pdf,vix,cpp");2
3
4
It adds visible page content:
auto &page = doc.add_page();Then it saves the document:
auto saved = rix.pdf.save(doc, "rix_pdf_metadata.pdf");Metadata is document information
PDF metadata is information stored in the PDF file.
It can describe the document, but it is not visible page content by itself.
Metadata can include:
title
author
subject
creator
keywords2
3
4
5
If you want text to appear on the page, draw it with:
page.text(...)
page.heading(...)
page.paragraph(...)2
3
Set the title
Use:
doc.set_title("Rix PDF Metadata Example");The title describes the document.
If you also want a visible title, draw it on the page:
page.heading(
page.x_left(),
page.y_top(),
"Rix PDF Metadata Example",
1);2
3
4
5
Set the author
Use:
doc.set_author("Rix");The author describes who created the document or who owns the content.
Set the subject
Use:
doc.set_subject("PDF metadata");The subject is a short description of what the document is about.
Set keywords
Use:
doc.set_keywords("rix,pdf,vix,cpp");Keywords are useful for search, indexing, and document organization.
Use a stable comma-separated string.
Set the creator
The default creator is:
rix/pdfYou can override it:
doc.set_creator("my-app");If the creator is set to an empty value, it is normalized back to:
rix/pdfChain metadata setters
Document metadata setters return the document, so they can be chained:
doc.set_title("Report")
.set_author("Rix")
.set_subject("Generated report")
.set_creator("my-app")
.set_keywords("report,rix,pdf");2
3
4
5
This is the preferred style for simple metadata setup.
Metadata with visible content
Metadata is not enough if you want the reader to see a title inside the page.
Use both:
doc.set_title("Monthly Report")
.set_author("Rix");
auto &page = doc.add_page();
page.heading(
page.x_left(),
page.y_top(),
"Monthly Report",
1);2
3
4
5
6
7
8
9
10
The metadata title describes the file.
The page heading appears in the PDF content.
Complete metadata report
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Generated Report")
.set_author("Rix")
.set_subject("PDF metadata example")
.set_creator("rix/pdf")
.set_keywords("rix,pdf,metadata,report");
auto &page = doc.add_page();
auto y = page.heading(
page.x_left(),
page.y_top(),
"Generated Report",
1);
y -= 15.0F;
page.paragraph(
page.x_left(),
y,
page.content_width(),
"This document includes metadata and visible page content.");
auto saved = rix.pdf.save(doc, "generated-report.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "generated-report.pdf");
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Run:
vix run metadata.cppAccess metadata directly
You can access the metadata object:
auto &metadata = doc.metadata();Then set values:
metadata.set_title("Direct metadata");
metadata.set_author("Rix");
metadata.set_subject("Direct metadata access");
metadata.set_keywords("rix,pdf");2
3
4
For normal usage, prefer document helpers:
doc.set_title(...)
doc.set_author(...)
doc.set_subject(...)
doc.set_keywords(...)2
3
4
Read metadata
You can read metadata values:
rix.debug.print("title:", doc.metadata().title());
rix.debug.print("author:", doc.metadata().author());
rix.debug.print("subject:", doc.metadata().subject());
rix.debug.print("creator:", doc.metadata().creator());
rix.debug.print("keywords:", doc.metadata().keywords());2
3
4
5
This is useful in tests, diagnostics, and adapters.
Clear metadata
Use:
doc.metadata().clear();This clears user-provided metadata and resets the creator to:
rix/pdfExample:
doc.set_title("Temporary")
.set_author("Rix");
doc.metadata().clear();2
3
4
After clearing, title and author are empty again.
Check if metadata is empty
Use:
if (doc.metadata().empty())
{
rix.debug.print("metadata is empty");
}2
3
4
The default creator does not make metadata non-empty.
empty() checks whether user-provided metadata such as title, author, subject, and keywords is empty.
Metadata and saving
Metadata is written when the document is saved:
auto saved = rix.pdf.save(doc, "metadata.pdf");It is also included when the document is written to bytes:
auto bytes = rix.pdf.write(doc);Both paths use the same document model.
Save the document
Use:
auto saved = rix.pdf.save(doc, "metadata.pdf");Check errors:
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}2
3
4
5
6
7
8
9
Write bytes instead of saving
Use:
auto bytes = rix.pdf.write(doc);Example:
auto bytes = rix.pdf.write(doc);
if (bytes.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(bytes.error()),
bytes.error().message());
return 1;
}
rix.debug.print("pdf bytes:", bytes.value().size());2
3
4
5
6
7
8
9
10
11
12
13
Use write for HTTP responses or custom output handling.
Use save for direct file output.
Metadata for generated reports
A report usually sets at least:
doc.set_title("Daily Report")
.set_author("My App")
.set_subject("Daily system report")
.set_keywords("report,daily,pdf");2
3
4
Then draws visible content:
auto &page = doc.add_page();
page.heading(
page.x_left(),
page.y_top(),
"Daily Report",
1);2
3
4
5
6
7
Use metadata for file identity.
Use page content for the reader.
Metadata for invoices
doc.set_title("Invoice INV-001")
.set_author("My Company")
.set_subject("Customer invoice")
.set_keywords("invoice,pdf,billing");2
3
4
Then draw invoice content normally with text, tables, and lines.
Metadata for exported data
doc.set_title("CSV Export")
.set_author("Rix")
.set_subject("Data export")
.set_keywords("csv,export,rix,pdf");2
3
4
This is useful when converting CSV or application data into a PDF report.
Use in a Vix project
Create a project:
vix new rix-pdf-metadata --app
cd rix-pdf-metadata2
Add Rix:
vix add rix/rix
vix install2
Make sure vix.app contains:
deps = [
"rix/rix",
]2
3
A minimal vix.app can look like this:
name = "rix-pdf-metadata"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"src/main.cpp",
]
include_dirs = [
"include",
"src",
]
deps = [
"rix/rix",
]
packages = [
"vix",
]
links = [
"vix::vix",
]2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Put the example code in:
src/main.cppBuild and run:
vix build
vix run2
Single-file usage
For examples, tests, and quick experiments:
vix run metadata.cppIf needed:
vix install -g rix/rix
vix run metadata.cpp2
For project usage, prefer:
vix add rix/rix
vix install2
and keep the dependency in vix.app:
deps = [
"rix/rix",
]2
3
Use only PDF with the facade
If you want the rix.* facade style but only want PDF mounted, define the feature macro before including rix.hpp:
#define RIX_ENABLE_PDF
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Metadata only");
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Metadata example");
auto saved = rix.pdf.save(doc, "metadata.pdf");
return saved.ok() ? 0 : 1;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
If you also want debug output:
#define RIX_ENABLE_PDF
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
doc.set_title("Metadata only");
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Metadata example");
auto saved = rix.pdf.save(doc, "metadata.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "metadata.pdf");
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Use the independent package
For independent usage, install:
vix add rix/pdf
vix install2
In vix.app:
deps = [
"rix/pdf",
]2
3
Then include:
#include <rix/pdf.hpp>Example:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
doc.set_title("Independent PDF")
.set_author("Rix");
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from rix/pdf");
auto saved = pdf.save(doc, "metadata.pdf");
return saved.ok() ? 0 : 1;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
The examples in this documentation prefer the public facade:
#include <rix.hpp>and:
rix.pdfCommon mistakes
Forgetting to install Rix
If rix.hpp is not found, install Rix first.
For a project:
vix add rix/rix
vix install2
For single-file usage:
vix install -g rix/rixPutting Rix in packages
Wrong:
packages = [
"rix/rix",
]2
3
Correct:
deps = [
"rix/rix",
]2
3
deps is for Vix Registry packages.
packages is for CMake package discovery.
Expecting metadata to appear on the page
Metadata describes the file.
It does not draw visible text.
Wrong expectation:
doc.set_title("Report");Visible page content requires:
page.heading(
page.x_left(),
page.y_top(),
"Report",
1);2
3
4
5
Forgetting to save after setting metadata
This only changes the document model:
doc.set_title("Report");To create the PDF file:
rix.pdf.save(doc, "report.pdf");Not checking save errors
Wrong:
rix.pdf.save(doc, "metadata.pdf");Correct:
auto saved = rix.pdf.save(doc, "metadata.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}2
3
4
5
6
7
8
9
10
11
Confusing creator and author
author usually describes the author or owner of the document content.
creator usually describes the application or library that generated the PDF.
Example:
doc.set_author("Rix")
.set_creator("rix/pdf");2
What you should remember
Create a document:
auto doc = rix.pdf.document();Set metadata:
doc.set_title("Rix PDF Metadata Example")
.set_author("Rix")
.set_subject("PDF metadata")
.set_keywords("rix,pdf,vix,cpp");2
3
4
Add visible content:
auto &page = doc.add_page();
page.heading(
page.x_left(),
page.y_top(),
"Metadata",
1);2
3
4
5
6
7
Save:
auto saved = rix.pdf.save(doc, "metadata.pdf");For project usage:
vix add rix/rix
vix install2
and keep:
deps = [
"rix/rix",
]2
3
Next step
Continue with make_text.
Next: Make text