February 2020 saw the release of PSPDFKit for Web 2020.1, which introduced our Instant Comments feature.
Instant Comments is a real-time document collaboration tool built on top of our powerful Instant engine. It enables users across a network to interact by commenting on selected text or adding comment discussion threads anywhere on a document using our server-backed Web SDK. Think Google Docs but with PDFs!
This blog post aims to shed some light on how we were able to make use of the flexibility of the PDF format to bring this feature to our users without compromising on the portability of PDFs. Along the way, it also provides readers with a glimpse of how PDFs work under the hood.
The Big Idea
We set out on the mission of adding a collaboration feature to PDFs that let users communicate and interact over a network. (Surprisingly, Adobe did not have this in mind in 1993 when PDFs were first launched!) Working closely with a customer of ours, we settled on a Google Docs-style comments feature that would allow users to highlight text to start comment threads on the side of the page. We also wanted to enable users to place comments anywhere on the page, which gave them the ability to comment on anything visible in the document. This capability is useful when dealing with PDF documents, which often consist of much more than simple text. On top of all this, we wanted to ensure that users could still easily export documents that external PDF clients could open, all without losing comment data.
What’s in the PDF Spec?
The PDF specification allows for annotation “replies” (see table 170 on page 392), which are PDF annotation objects that can reference other annotations to create chains of text (see our What Are Annotations? blog post for more information on PDF annotations). This is a useful feature that lets users attach notes and snippets of text to existing annotations, and these notes are expanded in place on most PDF viewer clients. We wanted to keep this feature while expanding on it by adding convenient, fast, and accessible comment threads that would allow users to quickly see their team’s comments on the side of the page without having to delve into an annotation or block any part of the page.
The spec may have some limitations, but it more than makes up for it in its flexibility. At its core, a PDF is a collection of objects of varying types, with varying properties, either directly or indirectly referencing each other using IDs (read more about PDF objects in our PDF Syntax 101 blog post). To render a page correctly, certain objects and their properties — connected in a specific structure — are required. Beyond this, you are free to write whatever data you wish inside these objects.
Ensuring we can handle and render the seemingly infinite amount of edge cases and nuances that can arise in PDFs is usually what keeps us busy. But the flexibility of the format also allows us to build features, such as Instant Comments, on top of the standard to make a more valuable and useful tool.
With Instant Comments, we wanted to show comments separate from text annotation replies. Generally, we would achieve this using the space to the side of the page so that the comments don’t interfere with the page itself.
It helps to define what the terms mean to draw a distinction between their different purposes:
PDF replies are defined in the PDF spec. Replies are extra details one may wish to add to an annotation. They’re usually expanded inside a document and are often used for more permanent and static information.
Instant Comments is a PSPDFKit-only feature. Comments are generally a shortlived, real-time collaboration tool. They’re used for quickly spawning discussions between multiple users anywhere on a document, and can be viewed immediately on the side of the page so they don’t block the page itself.
To prevent loss of data and to make sure any comment information is available in external readers, we store comments in a document as PDF replies when exporting the document. But we still need a way to identify them when we try to open the document. To do this, we convert all the comment data into a PDF
Text annotation. If a comment is in reply to a prior comment, we use the
IRT (In Reply To) field of the
Text annotation properties (part of the “replies” specification). This way, the comments will be viewable in an external reader.
But what about when we import a document to our platform? This is where the flexibility of the PDF document structure helps, as it allows us to add our own data (in the form of a dictionary entry, or key-value pair) to the underlying annotation data structure. We flag our Instant Comment threads with a Boolean dictionary entry labeled
"PSPDF:CommentThread": true, which allows us to identify which
Text annotations are actually Instant Comments and can be rendered in the sidebar (or however our users wish to display the comments).
Another limitation of PDF clients is that they don’t allow for users to quickly and easily “drop a pin” anywhere on a document to mark the start of a comment thread.
For this use case, we created another addendum to the PDF spec specifically for use in our SDK, and we call it a comment marker annotation.
Comment markers are a set of page coordinates marking the location of an Instant Comment thread. As with the comments (which hold the actual comment text), we need a way to retain the comment marker type and coordinate information when exporting and importing the document from and to our SDK.
As PDFs don’t know about the comment marker annotation type when exporting, we again converted these annotations into
Text annotations. This was problematic, due to the fact that we had a
Text annotation with no text associated with it! So when opening a document in an external reader, the comment thread information was often not accessible, as clients didn’t know how to display an empty
To fix this, we merged the first comment’s text into the PDF
Text annotation, along with the author, dates, and other useful information about the comment. We also made sure our handy
"PSPDF:CommentThread": true dictionary entry flagged
Text annotations. Now when someone opens a document in an external reader, users will see a comment as a
Text annotation with some text inside, and any replies to the first comment can be accessed as PDF
Text annotations, and so on down the chain of comments.
For a closer look at this, we can use our handy PDF Inspector app to see what an Instant Comment thread looks like inside a PDF.
Here we can see the comment marker object (
ObjNum:15) into which the first comment — with the
Contents “Hi there!” — is merged. The coordinates are stored in the
Rect Array. We can also see both the first reply to that comment (
ObjNum:14) and how these comments are linked using the
Importing the document into our SDK, we do the same thing in reverse. First we can identify the imported annotation as an Instant Comment thread by looking out for the
"PSPDF:CommentThread": true flag. Then we extract the coordinates into a PSPDFKit comment marker, and we extract the data out of the
Text annotation to be used as the first Instant Comment in the thread.
In this way, we can maintain compatibility with the PDF spec while building our features on top.
By taking advantage of the flexibility inherent in PDF data structures, we’re able to create new ideas and push the boundaries of what can be done with PDFs, all while maintaining the portability and reliability that keeps PDF the most popular format for sharing digital documents.
If you’re interested in reading more, our Introduction to Instant Comments guide is a great place to start. If you want to give Instant Comments a try and bring this exciting collaboration feature to your customers, head over to our Web and Server platform demo page, play around with it for free, and pick up a trial of PSPDFKit for Web.