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
Download sample

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 Document
from nutrient_sdk import PdfEditor
from nutrient_sdk import Color
from nutrient_sdk import NutrientException

Working 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 128 gives 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:

  1. Open the document using a context manager(opens in a new tab) for automatic resource cleanup.
  2. Create an editor and access the page collection.
  3. Ensure at least one page exists by adding a letter-size page if needed.
  4. Retrieve the annotation collection from the target page.
  5. Add highlight annotations with translucent overlays using add_highlight() for emphasizing content.
  6. Customize highlight transparency using ARGB alpha values (128 = 50 percent transparency).
  7. Add underline annotations with add_underline() for drawing attention beneath text.
  8. Add strikeout annotations with add_strike_out() for marking deleted or outdated content.
  9. Add squiggly annotations with add_squiggly() for indicating spelling or grammar issues.
  10. Customize text markup colors using the color property with ARGB color values.
  11. Position annotations with consistent vertical spacing to create organized markup sequences.
  12. Save and close the editor.

For related annotation workflows, refer to the Python SDK annotation guides.