Skip to main content

My preferred options for SmartyPants in Python

  • Posted
  • Updated

smartypants.smartypants(…, Attr.q | Attr.D | Attr.e | Attr.u)

I use the smartypants library, which adds curly quotes and dashes to some text in Python. This is my current configuration:

import smartypants


def smartify(text: str) -> str:
    """
    Add curly quotes and smart dashes to a string.
    """
    # Undo some escaping from Mistune.
    text = text.replace(""", '"')

    attrs = (
        # normal quotes (" and ') to curly ones
        smartypants.Attr.q
        |
        # typewriter dashes (--) to en-dashes and dashes (---) to em-dashes
        smartypants.Attr.D
        |
        # dashes (...) to ellipses
        smartypants.Attr.e
        |
        # output Unicode chars instead of numeric character references
        smartypants.Attr.u
    )

    return smartypants.smartypants(text, attrs)

I set four processing attributes to control the behaviour.

Mistune is the Python Markdown parser I use, which converts double quotes to ". I don’t think there’s a way to disable that behaviour.

Here’s a set of tests that check it’s doing what I expect:

import pytest


@pytest.mark.parametrize(
    "text, expected",
    [
        ("Isn't it delightful -- she said", "Isn’t it delightful – she said"),
        ("Are you ... sure?", "Are you … sure?"),
        ("<h2>Isn't it delightful?</h2>", "<h2>Isn’t it delightful?</h2>"),
        ("<li>Isn't it delightful?</li>", "<li>Isn’t it delightful?</li>"),
        ("<p>&quot;It's nice&quot;, he said</p>", "<p>“It’s nice”, he said</p>"),
    ],
)
def test_smartify(text: str, expected: str) -> None:
    """
    Test smartify().
    """
    actual = t.smartify(text)
    assert actual == expected