From nl-ai-lawyer
Create, manipulate, fill, merge, split, and process PDF documents for Dutch legal practice. Use this skill whenever the user wants to generate a legal PDF (contract, NDA, memorandum, dagvaarding, legal opinion), extract text/tables from legal PDFs, fill Dutch legal forms (KVK forms, court filings, notarial deeds), combine or split legal documents, add watermarks or confidentiality stamps, OCR scanned legal documents, or convert legal analysis into professional PDF output. Triggers on any mention of .pdf files in a Dutch legal context, requests to "generate a document", "create a contract PDF", "fill out a form", "make this into a PDF", or any legal document production task. Also use when the user asks to extract clauses, tables, or structured data from existing legal PDFs.
npx claudepluginhub futureatoms/falcon-futureatoms-legal-counsel-of-netherlandsThis skill uses the workspace's default tool permissions.
Generate, manipulate, and process PDF documents for Netherlands legal practice. This skill combines robust PDF tooling with Dutch legal formatting standards, mandatory disclaimers, and integration with the Netherlands AI Lawyer system.
dutch-legal-docs.mdforms.mdreference.mdscripts/check_bounding_boxes.pyscripts/check_fillable_fields.pyscripts/convert_pdf_to_images.pyscripts/create_legal_pdf.pyscripts/extract_form_field_info.pyscripts/extract_form_structure.pyscripts/fill_fillable_fields.pyscripts/fill_pdf_form_with_annotations.pyGuides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Automates semantic versioning and release workflow for Claude Code plugins: bumps versions in package.json, marketplace.json, plugin.json; verifies builds; creates git tags, GitHub releases, changelogs.
Generate, manipulate, and process PDF documents for Netherlands legal practice. This skill combines robust PDF tooling with Dutch legal formatting standards, mandatory disclaimers, and integration with the Netherlands AI Lawyer system.
reference.mdforms.mddutch-legal-docs.mdUser wants to...
├── CREATE a new legal PDF from scratch
│ → Use reportlab (Python) — see "Creating Legal PDFs" below
│ → Read dutch-legal-docs.md for document type templates
│
├── FILL an existing PDF form (KVK, court, government)
│ → Read forms.md and follow its step-by-step instructions
│
├── EXTRACT text/tables from a legal PDF
│ → Use pdfplumber for tables, pypdf for text
│
├── MERGE multiple legal documents
│ → Use pypdf or qpdf
│
├── SPLIT a legal document
│ → Use pypdf or qpdf
│
├── OCR a scanned legal document
│ → Use pytesseract + pdf2image
│
├── ADD watermark/confidentiality stamp
│ → Use pypdf page merging
│
└── CONVERT legal analysis to PDF
→ Use reportlab with legal templates below
Every legal PDF produced by this system must include:
assets/disclaimers/ (Dutch: disclaimer-nl.md, English: disclaimer-en.md). The disclaimer goes on the final page.These are non-negotiable. A legal PDF without a disclaimer is incomplete.
from pypdf import PdfReader, PdfWriter
# Read and extract text
reader = PdfReader("contract.pdf")
for page in reader.pages:
text = page.extract_text()
# Merge legal documents (e.g., contract + annexes)
writer = PdfWriter()
for pdf_file in ["hoofdovereenkomst.pdf", "bijlage-1.pdf", "bijlage-2.pdf"]:
reader = PdfReader(pdf_file)
for page in reader.pages:
writer.add_page(page)
with open("compleet-dossier.pdf", "wb") as f:
writer.write(f)
# Split: extract specific pages
reader = PdfReader("vonnis.pdf")
writer = PdfWriter()
writer.add_page(reader.pages[0]) # Just the first page (dictum)
with open("dictum.pdf", "wb") as f:
writer.write(f)
# Rotate
page = reader.pages[0]
page.rotate(90)
Particularly useful for extracting clause tables, fee schedules, and structured data from contracts or court rulings.
import pdfplumber
with pdfplumber.open("jaarrekening.pdf") as pdf:
for page in pdf.pages:
# Extract text preserving layout
text = page.extract_text()
# Extract tables (fee schedules, financial statements)
tables = page.extract_tables()
for table in tables:
for row in table:
print(row)
import pdfplumber
import pandas as pd
with pdfplumber.open("financieel-overzicht.pdf") as pdf:
all_tables = []
for page in pdf.pages:
tables = page.extract_tables()
for table in tables:
if table:
df = pd.DataFrame(table[1:], columns=table[0])
all_tables.append(df)
if all_tables:
combined = pd.concat(all_tables, ignore_index=True)
combined.to_excel("extracted_tables.xlsx", index=False)
This is the primary tool for generating legal documents from scratch.
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_JUSTIFY, TA_CENTER, TA_RIGHT
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from datetime import date
def create_legal_document(filename, title, content_blocks):
"""Create a professional Dutch legal PDF."""
doc = SimpleDocTemplate(
filename,
pagesize=A4,
leftMargin=2.5*cm,
rightMargin=2.5*cm,
topMargin=2.5*cm,
bottomMargin=2.5*cm
)
styles = getSampleStyleSheet()
# Dutch legal document styles
styles.add(ParagraphStyle(
'LegalTitle',
parent=styles['Title'],
fontSize=16,
spaceAfter=20,
alignment=TA_CENTER
))
styles.add(ParagraphStyle(
'LegalHeading',
parent=styles['Heading2'],
fontSize=12,
spaceBefore=16,
spaceAfter=8,
fontName='Helvetica-Bold'
))
styles.add(ParagraphStyle(
'LegalBody',
parent=styles['Normal'],
fontSize=10,
leading=14,
alignment=TA_JUSTIFY,
spaceAfter=6
))
styles.add(ParagraphStyle(
'LegalDisclaimer',
parent=styles['Normal'],
fontSize=8,
leading=10,
textColor=colors.grey,
alignment=TA_JUSTIFY,
spaceBefore=20
))
styles.add(ParagraphStyle(
'LegalFooter',
parent=styles['Normal'],
fontSize=8,
alignment=TA_RIGHT,
textColor=colors.grey
))
story = []
# Title
story.append(Paragraph(title, styles['LegalTitle']))
story.append(HRFlowable(width="100%", thickness=1, color=colors.black))
story.append(Spacer(1, 12))
# Content blocks
for block in content_blocks:
if block['type'] == 'heading':
story.append(Paragraph(block['text'], styles['LegalHeading']))
elif block['type'] == 'body':
story.append(Paragraph(block['text'], styles['LegalBody']))
elif block['type'] == 'table':
t = Table(block['data'], colWidths=block.get('colWidths'))
t.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#2C3E50')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, -1), 9),
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('VALIGN', (0, 0), (-1, -1), 'TOP'),
('BOTTOMPADDING', (0, 0), (-1, -1), 6),
('TOPPADDING', (0, 0), (-1, -1), 6),
]))
story.append(t)
story.append(Spacer(1, 12))
elif block['type'] == 'pagebreak':
story.append(PageBreak())
# Disclaimer (always last page)
story.append(PageBreak())
story.append(Paragraph("DISCLAIMER", styles['LegalHeading']))
story.append(Paragraph(
"Dit document is opgesteld met behulp van AI-ondersteunde analyse en vormt "
"<b>geen juridisch advies</b> in de zin van de Advocatenwet. De informatie is "
"uitsluitend informatief. Raadpleeg altijd een gekwalificeerde advocaat "
"(ingeschreven bij de Nederlandse Orde van Advocaten) voordat u juridische "
"beslissingen neemt. Aan dit document kunnen geen rechten worden ontleend.",
styles['LegalDisclaimer']
))
story.append(Spacer(1, 8))
story.append(Paragraph(
f"Gegenereerd door FALCON (FutureAtoms AI Legal Counsel Of Netherlands) | "
f"Datum: {date.today().strftime('%d-%m-%Y')} | "
f"Verificatiedatum wetgeving: {date.today().strftime('%d-%m-%Y')}",
styles['LegalFooter']
))
doc.build(story)
return filename
Never use Unicode subscript/superscript characters in ReportLab PDFs — they render as black boxes. Use XML markup tags instead:
from reportlab.platypus import Paragraph
styles = getSampleStyleSheet()
# Subscripts: <sub> tag
chemical = Paragraph("H<sub>2</sub>O", styles['Normal'])
# Superscripts: <super> tag
squared = Paragraph("x<super>2</super>", styles['Normal'])
# Extract text preserving layout
pdftotext -layout vonnis.pdf vonnis.txt
# Extract specific pages
pdftotext -f 1 -l 5 contract.pdf first-five-pages.txt
# Merge legal documents with annexes
qpdf --empty --pages hoofdovereenkomst.pdf bijlage-1.pdf bijlage-2.pdf -- dossier.pdf
# Split: extract pages 1-5
qpdf contract.pdf --pages . 1-5 -- samenvatting.pdf
# Decrypt password-protected document
qpdf --password=geheim --decrypt versleuteld.pdf ontsleuteld.pdf
# Encrypt with permissions (no printing, no copying)
qpdf --encrypt user_pw owner_pw 256 --print=none --modify=none -- input.pdf beschermd.pdf
import pytesseract
from pdf2image import convert_from_path
# Convert scanned PDF to searchable text
images = convert_from_path('gescand-vonnis.pdf')
text = ""
for i, image in enumerate(images):
# Use Dutch language model for better accuracy
text += f"--- Pagina {i+1} ---\n"
text += pytesseract.image_to_string(image, lang='nld')
text += "\n\n"
For Dutch legal documents, install the Dutch Tesseract language pack (nld) for significantly better OCR accuracy on Dutch text.
from pypdf import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
import io
def create_confidentiality_watermark():
"""Create a VERTROUWELIJK (CONFIDENTIAL) watermark."""
packet = io.BytesIO()
c = canvas.Canvas(packet, pagesize=A4)
c.saveState()
c.translate(A4[0]/2, A4[1]/2)
c.rotate(45)
c.setFont("Helvetica-Bold", 60)
c.setFillColor(colors.Color(1, 0, 0, alpha=0.15))
c.drawCentredString(0, 0, "VERTROUWELIJK")
c.restoreState()
c.save()
packet.seek(0)
return PdfReader(packet).pages[0]
def apply_watermark(input_pdf, output_pdf):
watermark = create_confidentiality_watermark()
reader = PdfReader(input_pdf)
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark)
writer.add_page(page)
with open(output_pdf, "wb") as f:
writer.write(f)
from pypdf import PdfReader, PdfWriter
reader = PdfReader("vertrouwelijk-advies.pdf")
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
# Encrypt: user password to open, owner password for full access
writer.encrypt("lezer-wachtwoord", "eigenaar-wachtwoord")
with open("beschermd-advies.pdf", "wb") as f:
writer.write(f)
# Using pdfimages (poppler-utils)
pdfimages -j bewijsstuk.pdf images/bewijs
# Extracts as bewijs-000.jpg, bewijs-001.jpg, etc.
When generating legal PDFs, leverage the existing legal domain skills:
| Document Type | Template Source | Legal Skill |
|---|---|---|
| Contract Review Report | assets/templates/contract-review-report.md | dutch-contract-review |
| Legal Memorandum | assets/templates/legal-memorandum.md | Multiple (domain-specific) |
| NDA / Geheimhoudingsovereenkomst | assets/templates/nda-template-nl.md | nda-triage-nl |
| Verwerkersovereenkomst (DPA) | assets/templates/verwerkersovereenkomst.md | dutch-privacy-gdpr |
| Arbeidsovereenkomst | assets/templates/arbeidsovereenkomst.md | dutch-employment-law |
Use the MCP tools to pull live legal data into documents:
legislation_get_article for exact statutory text, caselaw_search_rechtspraak for case law citationslegal_think for structured legal reasoning in document analysis sectionsDutch legal documents use hierarchical numbering:
Artikel 1, Artikel 21.1, 1.2, 1.31.1.1 or a., b., c.Always use Dutch format: 4 maart 2026 or 04-03-2026 (DD-MM-YYYY), never MM-DD-YYYY.
| Task | Best Tool | Notes |
|---|---|---|
| Create legal PDF | reportlab | Use A4, Dutch formatting |
| Merge documents + annexes | pypdf or qpdf | Maintain page numbering |
| Extract text from rulings | pdfplumber | Preserves layout |
| Extract tables | pdfplumber | Fee schedules, financial data |
| Fill government forms | See forms.md | KVK, court, IND forms |
| OCR scanned documents | pytesseract (lang=nld) | Use Dutch language model |
| Add VERTROUWELIJK stamp | pypdf merge | See watermark example above |
| Password protect | pypdf encrypt | Or qpdf for CLI |
| Extract images/evidence | pdfimages | poppler-utils |
| Convert to searchable PDF | pytesseract + reportlab | OCR then rebuild |
reference.mdforms.mddutch-legal-docs.md