Adding text markup annotations to a PDF document
Use text markup annotations to add review feedback directly on text in PDF files.
Common use cases include:
- Proofreading workflows
- Collaborative document review
- Content highlighting and emphasis
- Revision and deletion tracking
In this guide, you’ll add:
- Highlight annotations
- Underline annotations
- Strikeout annotations
- Squiggly annotations
- Custom colors for each markup type
How Nutrient helps
Nutrient Python SDK handles text markup annotation structures and appearance generation.
The SDK handles:
- Text markup dictionaries and quadrilateral arrays
- Translucent overlays and blend modes
- Coordinate calculations and bounding box intersections
- Appearance streams and color transformations
Complete implementation
This example adds several text markup annotations to a PDF file:
from nutrient_sdk import Documentfrom nutrient_sdk import PdfEditorfrom nutrient_sdk import Colorfrom nutrient_sdk import NutrientExceptionWorking with text markup annotations
Open the document in a context manager(opens in a new tab) so resources are cleaned up after processing.
Then:
- Create a PDF editor.
- Get the page collection.
- Add a letter-size page (
612 × 792) if the document is empty. - Get the annotation collection from the first page.
def main(): try: with Document.open("input.pdf") as document: editor = PdfEditor.edit(document) pages = editor.get_page_collection()
if pages.get_count() == 0: pages.add(612.0, 792.0)
page = pages.get_first() annotations = page.get_annotation_collection()Adding a highlight annotation
Add a highlight with add_highlight(x, y, width, height, author, contents).
In this sample:
- The position is
(50, 700). - The size is
150 × 20. - The color is set to translucent yellow with
Color.from_argb(128, 255, 255, 0). - The alpha value
128gives 50 percent opacity.
highlight = annotations.add_highlight( 50.0, 700.0, 150.0, 20.0, # x, y, width, height "Highlighter", "Important information" ) # Optionally customize the color highlight.color = Color.from_argb(128, 255, 255, 0)Adding an underline annotation
Add an underline with add_underline(x, y, width, height, author, contents).
In this sample:
- The position is
(50, 650). - The size is
150 × 20. - The color is set to blue with
Color.from_argb(255, 0, 0, 255).
underline = annotations.add_underline( 50.0, 650.0, 150.0, 20.0, # x, y, width, height "Underliner", "Emphasized text" ) # Optionally customize the color. underline.color = Color.from_argb(255, 0, 0, 255)Adding a strikeout annotation
Add a strikeout with add_strike_out(x, y, width, height, author, contents).
In this sample:
- The position is
(50, 600). - The size is
150 × 20. - The default color is red (
ARGB 255, 255, 0, 0). - Use this style to mark text for removal.
strike_out = annotations.add_strike_out( 50.0, 600.0, 150.0, 20.0, # x, y, width, height "Reviewer", "This content should be removed" )Adding a squiggly annotation
Add a squiggly underline with add_squiggly(x, y, width, height, author, contents).
In this sample:
- The position is
(50, 550). - The size is
150 × 20. - The color is changed to green with
Color.from_argb(255, 0, 128, 0). - Use this style to flag spelling or grammar issues.
squiggly = annotations.add_squiggly( 50.0, 550.0, 150.0, 20.0, # x, y, width, height "Proofreader", "Check spelling here" ) # Optionally customize the color squiggly.color = Color.from_argb(255, 0, 128, 0)Saving the document
Save the output PDF and close the editor.
The except block catches NutrientException if processing fails:
editor.save_as("output.pdf") editor.close() except NutrientException as e: print(f"Error: {e}")
if __name__ == "__main__": main()Conclusion
Use this workflow to add text markup annotations:
- Open the document using a context manager(opens in a new tab) for automatic resource cleanup.
- Create an editor and access the page collection.
- Ensure at least one page exists by adding a letter-size page if needed.
- Retrieve the annotation collection from the target page.
- Add highlight annotations with translucent overlays using
add_highlight()for emphasizing content. - Customize highlight transparency using ARGB alpha values (128 = 50 percent transparency).
- Add underline annotations with
add_underline()for drawing attention beneath text. - Add strikeout annotations with
add_strike_out()for marking deleted or outdated content. - Add squiggly annotations with
add_squiggly()for indicating spelling or grammar issues. - Customize text markup colors using the
colorproperty with ARGB color values. - Position annotations with consistent vertical spacing to create organized markup sequences.
- Save and close the editor.
For related annotation workflows, refer to the Python SDK annotation guides.