npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@inteli.city/node-red-contrib-latex-pdf

v1.0.0

Published

A Node-RED node that renders LaTeX using Nunjucks and compiles it to PDF using Tectonic.

Readme

node-red-contrib-latex-pdf

A Node-RED node that renders LaTeX using Nunjucks and compiles it to PDF using Tectonic.

Table of Contents


Overview

This node renders a Nunjucks template into a LaTeX document and compiles it to PDF using Tectonic.

The result is a PDF Buffer in msg.payload.

Requirements: Tectonic must be installed and available in PATH.

Install Tectonic: https://tectonic-typesetting.github.io/en-US/install.html


When to Use

Use this node when you need:

  • dynamic PDF generation
  • structured reports (logs, invoices, summaries)
  • embedding binary data (images, diagrams) into documents

Do not use this node for:

  • simple text formatting (use the built-in template node)
  • high-frequency, low-latency flows (PDF compilation is expensive)
  • very large documents (Tectonic runs per message)

Mental Model

This node executes a template as a document generation program.

  • payload → input data
  • template → logic + layout
  • asset() → converts Buffers into files for LaTeX

Think of it as:

data → template → files → PDF

The template controls rendering. The node does not transform data implicitly.


Contract

The node expects:

  • msg.payload — any data (including Buffers)
  • A valid Nunjucks template that produces valid LaTeX after rendering
  • No external file inputs — all files must be created via asset()

The node guarantees:

  • PDF output as a Buffer in msg.payload
  • Isolated execution per message (temporary directory)
  • Cleanup of all temporary files after execution

The node will fail if:

  • The template uses msg.* syntax
  • asset() receives a non-Buffer value
  • LaTeX compilation fails (Tectonic error)

Installation

cd ~/.node-red
npm install node-red-contrib-latex-pdf

How It Works

Nunjucks template → LaTeX → Tectonic → PDF → msg.payload

Each message is processed in an isolated temporary directory. All files (.tex, assets, output .pdf) are deleted after compilation.


Template Context

Message properties are exposed at the root of the template context. Reference them directly — do not use msg.*.

| Variable | Value | |---|---| | {{ payload }} | msg.payload | | {{ topic }} | msg.topic | | {{ flow.get("key") }} | Flow context variable | | {{ global.get("key") }} | Global context variable | | {{ env.MY_VAR }} | OS environment variable |

Using msg. inside a template triggers a node error. Use {{ payload }} style instead.


Rendering Data

msg.payload is passed to the template as-is — no automatic stringification.

To render objects as text, use the dump filter:

{{ payload | dump }}

This is required to preserve Buffers and binary data. Passing a raw object to LaTeX without dump will render as [object Object].


Inline Assets (asset helper)

asset() is the only supported way to embed files. It writes a Buffer to a temporary file and returns the filename for LaTeX to reference:

\includegraphics{ {{ asset(payload.image, "png") }} }

Each call generates a unique filename (asset-0.png, asset-1.png, …).

Loops are supported:

{% for img in payload.images %}
\includegraphics{ {{ asset(img, "png") }} }
{% endfor %}

Constraints:

  • First argument must be a Buffer — anything else throws an error
  • Extension is sanitized (alphanumeric only); defaults to bin
  • Files are not persisted after execution

Error Handling

The node fails fast on invalid input. Errors are reported via node.error() and attached to msg.error.

| Situation | Error message | |---|---| | Template uses msg.* | Use {{ payload }} style, not {{ msg.* }}. | | asset() receives non-Buffer | asset() expects a Buffer | | Tectonic compilation fails | Tectonic stderr output |

The queue continues processing subsequent messages after a failure.


Queue / Concurrency

The node processes messages using a FIFO queue with configurable concurrency.

Set the Queue field in the node editor to control how many compilations can run in parallel. Default is 1 (fully sequential).

Status format:

<queued> (<running>/<max>)

Examples:

0 (0/1)   → idle
0 (1/1)   → one compiling
3 (5/5)   → saturated, 3 waiting

Examples

Basic — render text payload

\documentclass{article}
\begin{document}
{{ payload | dump }}
\end{document}

Report with image

\documentclass{article}
\usepackage{graphicx}
\begin{document}

\section*{ {{ payload.title }} }

{{ payload.description }}

\includegraphics{ {{ asset(payload.image, "png") }} }

\end{document}

Multiple images

\documentclass{article}
\usepackage{graphicx}
\begin{document}
{% for img in payload.images %}
\includegraphics{ {{ asset(img, "png") }} }
{% endfor %}
\end{document}

Limitations

Templates are rendered from a single string. The following Nunjucks features are not supported:

  • {% include "file.njk" %}
  • {% extends "base.njk" %}
  • {% import "macros.njk" %}

Templates must be self-contained. Macros can be defined and used within a single template.

  • Files must be provided as Buffers inside the template via asset()

Full Nunjucks documentation (not all features are supported): https://mozilla.github.io/nunjucks/templating.html