Hanging Punctuation in Pandoc

A lua filter for Pandoc which allows curly quotes to hang into the margin.

@jez

This project provides a lua filter for Pandoc along with some CSS styles which together allow curly quotes to hang into the margin. Here’s an example:


How do you call among you the little mouse, the mouse that jumps?” Paul asked, remembering the pop-hop of motion at Tuono Basin. He illustrated with one hand. A chuckle sounded through the troop. We call that one muad’dib,” Stilgar said.

— Frank Herbert, Dune


Note how the on the first line hangs into the margin. But also, depending on the screen width, the mid-paragraph quote starting “We ... may also hang into the margin:

The same quote, at a small screen size
The same quote, at a small screen size

This effect is not possible with the hanging-punctuation CSS property. Safari supports it, but only for the very first quotation mark in a block. All other browsers do not support it.

By contrast, this filter allows quotation characters to hang into the margin even in the middle of body text, and works in all browsers.

For more, read about hanging punctuation on Wikipedia.

Usage

  1. Download the hanging-punctuation.lua file:

    curl -sSLO https://raw.githubusercontent.com/jez/pandoc-hanging-punctuation/refs/heads/master/hanging-punctuation.lua
  2. Download the hanging-punctuation.css file:

    curl -sSLO https://raw.githubusercontent.com/jez/pandoc-hanging-punctuation/refs/heads/master/hanging-punctuation.css
  3. Pass these files when invoking pandoc:

    pandoc -f markdown -t html index.md \
      --standalone \
      --lua-filter=./hanging-punctuation.lua \
      --css ./hanging-punctuation.css > index.html

    The input must either use and quotes directly, or have the smart extension enabled.

    The smart extension is on by default in Pandoc’s markdown input format, but off by default in others, including the commonmark format. Enable it by passing +smart to the format when invoking pandoc, like -f commonmark+smart.

    See the Pandoc docs for more:

  4. Modify the hanging-punctuation.css file to set the two root CSS variables:

    /* -- hanging-punctuation.css -- */
    :root {
      /**
       * These widths will vary with font-family, font-weight, etc.
       * TODO: Customize these values as needed
       */
      --single-quote-width: 0.275em;
      --double-quote-width: 0.44em;
    }
    
    /* ... */

    These variables declare how big and characters are in the chosen font. Different font settings, like the family and weight, will affect the width.

    To determine a value for these variables, use a document like this:

    ---
    title: test
    ---
    
    Hello\
    "Hello"\
    Hello\
    'Hello'\
    Hello

    Render this markdown to HTML, then use the browser’s developer tools to vertically align all the H characters.

    As a a trick, on some operating systems you can use the system screenshot tool as a quick way to check if things are aligned and measure pixels distances on the screen.

  5. Ensure that no other CSS in the page sets the hanging-punctuation property.

    Either edit that CSS to remove mentions of it, or write CSS to forcibly override any inherited hanging-punctuation settings.

Caveats

Inspiration

This filter is heavily inspired by Typeset, An HTML pre-processor for web typography.” Compared to Typeset, this project:

Typeset includes other features which could be handled separately if desired (like auto-soft-hyphenation and certain other punctuation substitutions). The markup structure in this project is borrowed from Typeset.

It’s also inspired by Dropbox Paper, which includes support for hanging punctuation, and has inspired my other writing-focused tools. In particular, this website is uses my Pandoc Markdown CSS Theme, which draws heavy inspiration from the look of Dropbox Paper.



Testing

Hello
Hello”
Hello
Hello’
Hello

↑ Back to top