๐ Quick Reference Patterns
Minimal PDF, accessible PDF, and the 10-step accessibility checklist โ all as copy-paste-ready code blocks.
A comprehensive reference designed for coding LLMs (GitHub Copilot, ChatGPT, Claude, etc.) to generate correct, accessible PDFs using ObviousPDF. ๐ฅ Download Markdown
Minimal PDF, accessible PDF, and the 10-step accessibility checklist โ all as copy-paste-ready code blocks.
Text, graphics, images, transforms, annotations, forms, bookmarks, page labels, Form XObjects, encryption, signatures, gradients, patterns, layers, associated files, document parts, and colour spaces.
All required steps for PDF/UA: structure trees, alt text, BBox, reading order, artifacts, language, heading hierarchy, table semantics, link structure, and form tooltips.
Known mistakes LLMs make: forgetting DisplayDocTitle, mismatched begin/end calls, missing BBox on figures, unbalanced graphics state, and more.
using ObviousPDF;
using ObviousPDF.Accessibility;
var doc = new PdfDocument();
doc.Language = "en-US"; // Required
doc.Info.Title = "My Document"; // Required
doc.DisplayDocTitle = true; // Required
doc.PdfUaConformance = PdfUaConformanceLevel.PdfUA1;
var root = doc.EnableTaggedPdf();
var sect = root.AddChild(StructureType.Sect);
var h1 = sect.AddChild(StructureType.H1);
var para = sect.AddChild(StructureType.P);
var page = doc.AddPage();
page.AddTaggedText(h1, "Title", 72, 720,
new PdfTextOptions {
Font = StandardFont.HelveticaBold,
FontSize = 24 });
page.AddTaggedText(para, "Body text.", 72, 690);
page.AddArtifactText("Page 1", 285, 30,
PdfArtifactType.Pagination);
var report = new PdfAccessibilityChecker().Check(doc);
// report.IsFullyCompliant โ true โ
doc.Save("accessible.pdf");
using ObviousPDF;
var doc = new PdfDocument();
doc.EnableAccessibility("en-US", "My Document");
// โ Sets Language, Title, DisplayDocTitle, PdfUA1, tagged PDF, auto-tagging
var page = doc.AddPage();
page.AddText("Title", 72, 720, // auto-tagged as <P>
new PdfTextOptions { Font = StandardFont.HelveticaBold, FontSize = 24 });
page.AddText("Body text.", 72, 690); // auto-tagged as <P>
var img = PdfImage.FromJpegFile("photo.jpg");
page.AddImage(img, 72, 500, 200, 100,
"Photo description"); // auto-tagged as <Figure>
page.AddArtifactText("Page 1", 285, 30,
PdfArtifactType.Pagination); // artifact (unchanged)
doc.Save("easy_accessible.pdf");
Use EnableAccessibility() for quick documents. For rich semantics (headings, tables, lists), use manual tagging with EnableTaggedPdf(). Both approaches can be combined.
| # | Step | Code |
|---|---|---|
| 1 | Set document language | doc.Language = "en-US" |
| 2 | Set title | doc.Info.Title = "..." |
| 3 | Display title | doc.DisplayDocTitle = true |
| 4 | Enable tagging | doc.EnableTaggedPdf() |
| 5 | Tag all content | AddTaggedText(), BeginTaggedContent() |
| 6 | Mark decorative content | BeginArtifact(), AddArtifactText() |
| 7 | Alt text + BBox on figures | AddChild(Figure, "alt"); fig.BBox = ... |
| 8 | Heading hierarchy H1โH2โH3 | No skipping levels |
| 9 | Table headers with scope | AddHeaderCell(scope, id) |
| 10 | Validate | new PdfAccessibilityChecker().Check(doc) |
ObviousPDF.Json)Complete reference for AI assistants generating ObviousPDF JSON documents. ๐ฅ JSON Schema (draft-07) ๐ Form 1040 Example
ObviousPDF.Json is a JSON-to-PDF pipeline. Produce a single JSON document describing the
entire PDF โ pages, content, fonts, images, forms, accessibility structure, encryption, layers, gradients,
digital signatures, bookmarks โ and pass it to PdfJsonRenderer to get a valid binary PDF.
using ObviousPDF.Json;
// From a JSON string โ byte[]
byte[] pdf = PdfJsonRenderer.Render(jsonString);
// From a .json file path โ byte[]
byte[] pdf = PdfJsonRenderer.RenderFromFile("document.json");
// Build PdfDocument for further manipulation, then save yourself
PdfDocument doc = PdfJsonRenderer.BuildDocument(jsonString);
doc.Save("output.pdf");
The root object has 15 keys. Only pages is required.
| Key | Type | Required | Description |
|---|---|---|---|
pages | array | โ | Page definitions. At least one required. |
coordinateOrigin | string | No | "bottomLeft" (default, native PDF) or "topLeft" (screen-style, Y increases downward). Overridable per page. |
tagged | boolean | No | true to enable tagged PDF. Required for accessibility. |
accessible | boolean | No | true enables full PDF/UA-1: tagged PDF, conformance, display-doc-title, and auto-tagging (text โ <P>, images with altText โ <Figure>). No structureTree or structureId needed. New in v1.2.0. |
document | object | No | Info, language, pdfVersion, conformance, encryption, signature, linearize, xref/object stream settings. |
fonts | array | No | Font library. Referenced via options.fontRef in content. |
images | array | No | Image library. Referenced via imageRef on image elements. |
formXObjects | array | No | Reusable FormXObject templates. Referenced via ref on formXObject elements. |
layers | array | No | OCG layer declarations. Referenced via layerRef on layer elements. |
shadings | array | No | Axial/radial gradient declarations. Referenced via shadingId. |
patterns | array | No | Tiling pattern declarations. Referenced via patternId. |
attachments | array | No | Embedded file attachments. |
outlines | array | No | Bookmark/outline tree (nestable via children). |
pageLabels | array | No | Page label ranges (e.g. i, ii, iii then 1, 2, 3). |
structureTree | object | No | Tagged PDF logical structure root. Required when tagged: true. |
roleMappings | array | No | Custom structure type โ standard type mappings. |
All positions are in points (1 pt = 1/72 inch). Named page sizes:
| size | Width ร Height (pt) |
|---|---|
"Letter" | 612 ร 792 |
"Legal" | 612 ร 1008 |
"A4" | 595 ร 842 |
"A3" | 842 ร 1191 |
"A5" | 420 ร 595 |
"Tabloid" | 792 ร 1224 |
For custom sizes use "width" and "height" instead of "size". With "topLeft" origin, 1-inch margins = x:72, y:72 from the top-left. With "bottomLeft" origin on Letter, 1-inch top-left margin = x:72, y:720.
A color value is a named string, an RGB object, a grayscale object, or a CMYK object. All numeric components are 0.0 โ 1.0.
"color": "black" // named
"color": { "r": 0.2, "g": 0.4, "b": 0.8 } // DeviceRGB
"color": { "gray": 0.5 } // DeviceGray (0=black, 1=white)
"color": { "c": 0, "m": 0.75, "y": 1.0, "k": 0 } // DeviceCMYK
Named colors: "black" "white" "red" "green" "blue"
| mode | Required fields | PDF/UA safe? |
|---|---|---|
"standard" | standardFont | โ Not embedded |
"bundled" | bundledFont | โ Embedded, full Unicode |
"file" | path | โ Embedded |
"base64" | data | โ Embedded |
Standard font enum values: Helvetica HelveticaBold HelveticaOblique HelveticaBoldOblique Times TimesBold TimesItalic TimesBoldItalic Courier CourierBold CourierOblique CourierBoldOblique Symbol ZapfDingbats
Every element in a content array has a required "type" string. All elements additionally accept: structureId (string), artifact (bool), artifactType ("pagination"/"layout"/"page"/"background"), artifactSubtype ("Header"/"Footer").
| type | Key Properties |
|---|---|
text | text (string), x, y, options |
textBlock | lines (string[]), x, y, options |
image | imageRef or source (inline), x, y, width, height, scaleMode ("exact"/"fit"/"stretch"), altText (string โ auto-creates <Figure> with accessible: true) |
line | x1, y1, x2, y2, drawOptions |
rectangle | x, y, width, height, mode ("draw"/"fill"/"drawAndFill"), drawOptions |
circle | cx, cy, r, mode, drawOptions |
ellipse | cx, cy, rx, ry, mode, drawOptions |
polygon | points ([[x,y],...]), mode, drawOptions |
path | operations (moveTo/lineTo/curveTo/closePath), render ("stroke"/"fill"/"fillAndStroke"), drawOptions |
link | uri, x, y, width, height |
textAnnotation | x, y, contents, color, open |
freeTextAnnotation | x, y, width, height, contents, options, color |
markupAnnotation | markupType ("highlight"/"underline"/"squiggly"/"strikeOut"), x, y, width, height, color |
stampAnnotation | icon, x, y, width, height, color |
formXObject | ref (library id), x, y, width, height |
textField | name, x, y, width, height, tooltip, defaultValue, multiline, password, maxLength, fontSize, readonly, required, anchor |
checkboxField | name, x, y, width, height, tooltip, checked, readonly, required |
dropdownField | name, x, y, width, height, tooltip, options (string[]), selectedIndex, fontSize, readonly, required |
listBoxField | name, x, y, width, height, tooltip, options (string[]), selectedIndex, fontSize, readonly, required |
pushButtonField | name, x, y, width, height, tooltip, label |
signatureField | name, x, y, width, height, tooltip |
transform | operation ("translate"/"scale"/"rotate"/"skew"/"matrix"), operation params (tx/ty, sx/sy, angle, angleX/angleY, matrix[6]), content[] |
clip | shape ("rectangle"/"circle"/"ellipse"), shape params, content[] |
layer | layerRef (library id), content[] |
shading | shadingId (library id), x, y, width, height |
tilingPattern | patternId (library id), x, y, width, height |
alpha | strokeAlpha (0โ1), fillAlpha (0โ1), content[] |
options object)| Property | Type / Default | Description |
|---|---|---|
fontRef | string | Font library id. |
fontSize | number / 12 | Size in points. |
color | color | Fill color. |
leading | number | Line spacing (baseline to baseline). Default: fontSize ร 1.2. (Not lineHeight.) |
renderingMode | string / "fill" | "fill" ยท "stroke" ยท "fillAndStroke" ยท "invisible" |
alignment | string / "left" | "left" ยท "center" ยท "right" ยท "justify". Requires width. |
width | number | Max width for wrapping/alignment. |
decoration | string[] | ["underline"] / ["strikeOut"] / ["overline"] |
decorationColor | color | |
decorationThickness | number | |
superscript | bool / false | |
subscript | bool / false | |
outlineColor | color | Stroke color for outlined text. |
outlineWidth | number | Stroke width in points. |
backgroundColor | color | Highlight behind text. |
shadowColor | color | |
shadowOffsetX | number / 1.0 | |
shadowOffsetY | number / -1.0 | |
rotation | number / 0 | Degrees, counter-clockwise. |
drawOptions object)| Property | Type / Default | Description |
|---|---|---|
strokeColor | color | |
fillColor | color | |
lineWidth | number / 1.0 | Stroke width in points. |
lineCap | string / "butt" | "butt" / "round" / "projecting" |
lineJoin | string / "miter" | "miter" / "round" / "bevel" |
miterLimit | number / 10.0 | |
dashPattern | number[] | e.g. [5, 3] = 5pt dash, 3pt gap. |
dashPhase | number / 0 | |
strokeAlpha | number / 1.0 | 0.0โ1.0 |
fillAlpha | number / 1.0 | 0.0โ1.0 |
The structureTree node properties: type (required), id, altText (required for Figure), actualText, language, title, phoneme, phonemeAlphabet ("ipa"/"xSampa"), customType, children[].
Common structure types: Document Part Sect Div P H1โH6 L LI Lbl LBody Table TR TH TD Figure Form Span Link Note
{
"coordinateOrigin": "topLeft",
"tagged": true,
"document": {
"language": "en-US",
"displayDocTitle": true,
"info": { "title": "My Report" },
"conformance": { "pdfUa": "PdfUA1" }
},
"fonts": [{ "id": "body", "mode": "bundled", "bundledFont": "NotoSans" }],
"structureTree": {
"type": "Document",
"children": [
{ "type": "H1", "id": "h1" },
{ "type": "P", "id": "p1" }
]
},
"pages": [{
"size": "Letter",
"content": [
{ "type": "text", "structureId": "h1", "text": "Report Title",
"x": 72, "y": 72, "options": { "fontRef": "body", "fontSize": 20 } },
{ "type": "textBlock", "structureId": "p1",
"lines": ["First paragraph of content."],
"x": 72, "y": 108, "options": { "fontRef": "body", "fontSize": 11 } },
{ "type": "rectangle", "artifact": true, "artifactType": "layout",
"x": 72, "y": 770, "width": 468, "height": 1,
"drawOptions": { "strokeColor": { "gray": 0.7 } } }
]
}]
}
{
"accessible": true,
"document": {
"language": "en-US",
"info": { "title": "My Report" }
},
"fonts": [{ "id": "body", "mode": "bundled", "bundledFont": "NotoSans" }],
"pages": [{
"size": "Letter",
"content": [
{ "type": "text", "text": "Report Title",
"x": 72, "y": 72, "options": { "fontRef": "body", "fontSize": 20 } },
{ "type": "textBlock",
"lines": ["First paragraph of content."],
"x": 72, "y": 108, "options": { "fontRef": "body", "fontSize": 11 } },
{ "type": "rectangle", "artifact": true, "artifactType": "layout",
"x": 72, "y": 770, "width": 468, "height": 1,
"drawOptions": { "strokeColor": { "gray": 0.7 } } }
]
}]
}
"document": {
"encryption": {
"userPassword": "open123",
"ownerPassword": "admin456",
"algorithm": "Aes256",
"allowPrinting": true,
"allowCopying": false,
"allowModifying": false,
"allowAnnotating": false
}
}
{
"layers": [{ "id": "bg", "name": "Background", "visible": true }],
"shadings": [{
"id": "grad", "type": "axial",
"x0": 0, "y0": 0, "x1": 0, "y1": 792,
"colorStops": [
{ "offset": 0.0, "color": { "r": 0.2, "g": 0.5, "b": 0.9 } },
{ "offset": 1.0, "color": { "r": 0.9, "g": 0.9, "b": 1.0 } }
]
}],
"patterns": [{
"id": "dots", "width": 8, "height": 8,
"content": [{ "type": "circle", "cx": 4, "cy": 4, "r": 1.5,
"mode": "fill", "drawOptions": { "fillColor": { "gray": 0.8 } } }]
}],
"pages": [{
"size": "Letter",
"content": [
{ "type": "layer", "layerRef": "bg",
"content": [
{ "type": "shading", "shadingId": "grad",
"artifact": true, "x": 0, "y": 0, "width": 612, "height": 792 }
]
},
{ "type": "tilingPattern", "patternId": "dots",
"artifact": true, "x": 0, "y": 0, "width": 612, "height": 792 }
]
}]
}
{
"document": {
"signature": {
"certificatePath": "C:/certs/my-cert.pfx",
"certificatePassword": "secret",
"reason": "Document approved",
"signerName": "Jane Smith",
"fieldName": "Sig1",
"pageIndex": 0, "x": 72, "y": 700, "width": 200, "height": 50
}
},
"pages": [{
"size": "Letter",
"content": [
{ "type": "signatureField", "name": "Sig1",
"x": 72, "y": 700, "width": 200, "height": 50,
"tooltip": "Approval signature" }
]
}]
}
| Problem | Fix |
|---|---|
| Content at wrong Y position | Set coordinateOrigin once. With "topLeft", Y increases downward. With "bottomLeft" on Letter, top = y:792. |
| Font not found | Verify options.fontRef exactly matches the font entry id (case-sensitive). |
| Images not loading | Use absolute paths or "base64" mode for portability across environments. |
| Tagged PDF accessibility check fails | Use "accessible": true for auto-tagging (simplest). Or with manual tagging: every real-content element needs structureId. Every Figure structure node needs altText. Every form field needs tooltip. |
options wrong type on dropdown | On dropdownField / listBoxField, options is a string array (the choices), not a text options object. |
| Signature not applied | document.signature.fieldName must exactly match the name of a signatureField element on the page. |
| Line spacing too tight/wide | Use leading (not lineHeight) in text options. Default is fontSize ร 1.2. |
| Standard fonts fail PDF/UA | Use mode: "bundled" or mode: "file". Standard fonts are never embedded. |