Skip to content

pdfview API

Benjamin Gray edited this page Apr 29, 2020 · 18 revisions

⚠️ The service is currently open to large breaking changes, and should only be considered stable once version 1.0.0 is reached.

The following describes the public interface provided by the pdfview service. This service allows packages to subscribe to events on PDFs open in Atom, such as clicks, and to trigger actions such as scrolling to a position.

Other PDF providing / using packages are encouraged to contribute to this service API (please raise an issue with the suggestion first). The goal is to define something that is useful for PDF requiring packages (e.g., atom-latex), but also natural for PDF providing packages (e.g., this one) to implement.

Registration

An example of how to interact with it via a package is as follows.

  • In your package.json file, consume the pdfview service. E.g.,
"consumedServices": {
  "pdfview": {
    "versions": {
      "0.2.0": "consumePdfview"
    }
  }
}
  • In your package entry point, have the corresponding method consumePdfview (or whatever you chose to call it, so long as it matches what you declared in the package.json)
const {CompositeDisposable} = require("atom");
module.exports = {
  activate() {
    this.subscriptions = new CompositeDisposable();
  }
  deactivate() {
    this.subscriptions.dispose(); // remove subscriptions when this package is disabled
  }
  consumePdfview(pdfview) {
    // do something for every opened PDF
    this.subscriptions.add(pdfview.observePdfViews(pdf => {
      // subscribe to click events on that opened PDF
      this.subscriptions.add(pdf.onDidClick(event => {
        // print the PdfMouseEvent
        console.log(event);
      }));
    }));
  }
}

After reloading, every time you click the page you should see the event logged in the dev console.

Versions

v0.2.1

NOTE: All following objects, are only interfaces. They do not imply a particular result for typeof, instanceof, constructor.name, etc. The only guarantee of a package providing this service is that these properties exist and function as described.

PdfEvents

The entry point of the service; the function registered as the consumer is passed a PdfEvents object as the first argument. The returned Disposable can be used to unhook the subscription when finished (e.g., when consumer package is disabled). Providers should see the Atom Emitter utility class to easily create these disposables.

  • observePdfViews(cb: (pdf: PdfView) => void): Disposable

    • This method takes a callback and calls it once on every current PDF, and on every future PDF upon opening. The callback is passed a PdfView as the first argument, which represents the corresponding open PDF.
  • onDidOpenPdfView(cb: (pdf: PdfView) => void): Disposable

    • Same as PdfEvents#observePdfViews, but is only called on PDFs opened after the consumer has registered.
  • To open a specific PDF, it is expected for consumers to use the atom.workspace.open method. PDF viewers supporting this service should add an opener for .pdf files, and the resolved item must be the PdfView. Note that this may open a new view, or return an existing one. If creating a new view, the observePdfViews and similar methods will be triggered.

    • If you have a use case this does not support, please raise an issue.

PdfView

An interface to a single open PDF, similar to an Atom TextEditor. The returned Disposables can be used to unsubscribe to the events.

  • getPath()
    • Returns the absolute path of the PDF file, or undefined if it does not exist.
  • getUri()
    • Returns a URI of the PDF file. The URI used to open the file if opened through atom.workspace.open should be used if applicable.
    • Note that URIs made by Atom (e.g., tree-view package) may just be an absolute path.
  • onDidInteract(cb: (evt: PdfMouseEvent) => void): Disposable
    • Subscribes to an event the viewer treats as mouse "interaction". Use this to leave interpretation of interaction up to viewer instead of consumer.
      • E.g., viewers might make it equivalent to onDidClick with the ctrl key pressed.
    • This event should be fired in addition to the interactions regular event.
  • onDidClick(cb: (evt: PdfMouseEvent) => void): Disposable
    • Subscribes a callback to click events on this editor. This is only guaranteed to fire when the click is on a PDF page. The callback is passed a PdfMouseEvent as the first argument, representing the location of the click and other contextual information.
    • This will fire twice before a double click. See the dblclick documentation for what is expected behaviour.
    • Not all events are required to be reported. If the viewer is incapable of detecting certain context, such as held down keys, they just won't report them as held in the event. If the viewer feels the event was only meant for the viewer (e.g., panning the display), they do not need to report it.
    • It is up to the consumer to offer customising which events it reponds to, or the user to pick a different viewer that supports the required events.
  • onDidDoubleClick(cb: (evt: PdfMouseEvent) => void): Disposable
    • Same as onDidClick, but only triggers on a double click.
  • scrollToPosition(pos: PdfPosition)
    • Focuses the PDF on the provided PdfPosition. The exact location of the focus (centred, top left, etc) is not specified.
    • TODO: Add optional param as second argument to
      • hint focus location (top left, centred, etc.)
      • request small flash at the exact location
  • setAutoReload(enabled: boolean) (default: true)
    • Configures the reload behaviour of the PDF viewer for this PDF. Use false to prevent the viewer from automatically reloading the PDF when the file changes. To manually trigger a reload, see PdfView#reload. If true the viewer may reload the PDF contents automatically. It is possible the viewer may not do so even if enabled (e.g., if they are incapable), in which case this method is a no-op.
  • reload()
    • Call to trigger a reload of the PDF contents.
  • getDimensions(page: number): Promise<{width: number, height: number}>
    • Returns a promise that resolves to the crop box height and width of the provided page. Can be used to convert coordinates between different origins.

PdfMouseEvent

An object representing a click on a PDF

  • position: PdfPositionWithDimen
    • The location of the click.
  • altKey
  • button
  • buttons
  • ctrlKey
  • metaKey
  • shiftKey
    • For the above, see the MouseEvent documentation. No other properties documented there can be expected.

PdfPosition

A location on a PDF, specified by page number and PDF points from the pages User Space origin. This is typically the bottom left corner of the display. A PDF point is 1/72 inches (see the PDF spec for more details).

  • pageIndex
    • The page of the PDF. Pages start at 0.
  • pointX
    • The horizontal offset in PDF points User Space origin. Increases to the right.
  • pointY
    • The vertical offset in PDF points from the User Space origin. Increases upwards.

PdfPositionWithDimen (extends PdfPosition)

A location on a PDF that also includes the width and height of the page Crop Box in PDF points. This, with the pointX and pointY values, can typically be used to derive the relative location on the page from any corner.

This is not completely reliable, as the origin may be at any location relative to the page. It should work in practice though, unless the user has purposely moved the origin somewhere else. If you have a more reliable way to convey the relative position within the Crop Box, please raise an issue.

  • width
    • The total width of the page
  • height
    • The total height of the page
Clone this wiki locally