Pandoc Python Library

repository·master·Indexed 41 days ago

https://github.com/boisgera/pandoc

A Python library providing a Pythonic interface to the Pandoc document model. It allows developers to programmatically analyze, create, and transform documents using functions like pandoc.read() and pandoc.write(), and a comprehensive set of types in pandoc.types for manipulating blocks, inlines, and metadata.

Tokens
67.5K
Snippets
275
Records
304
Agent score
49%

What's inside Pandoc

  1. What is the pandoc.labs module?

    master

    The pandoc.labs module is an experimental feature set within the pandoc library. It provides a Query object (returned by the query() function) that acts as a collection of document elements. This collection allows for parallel operations and "no-failure" searching, meaning operations that find no matches return an empty collection rather than raising an error.

    Warning: The interface for pandoc.labs is highly unstable and should not be used for production applications.

    import pandoc
    from pandoc.types import *
    from pandoc.labs import *
    
    HELLOWORLD_DOC = pandoc.read("Hello world!")
    q = query(HELLOWORLD_DOC)
  2. Use the `styles` extension for docx conversion

    master

    When converting from docx, this extension forces Pandoc to read all docx styles as divs (for paragraph styles) and spans (for character styles), even if Pandoc does not recognize the specific meaning of the styles. This is useful for preserving custom styles.

    Supported Formats:

    • Input: docx
  3. Use the `intraword_underscores` extension for emphasis

    master

    The intraword_underscores extension allows emphasis to be applied to parts of a word (e.g., feas*ible*).

    >>> "feas*ible*, not feas*able*." # doctest: +PANDOC
        Pandoc(Meta(map()), [Para([Str(u'feas'), Emph([Str(u'ible')]), Str(u','), Space(), Str(u'not'), Space(), Str(u'feas'), Emph([Str(u'able')]), Str(u'.')])])
  4. Access and modify Pandoc elements as containers

    master

    All concrete Pandoc elements (e.g., Pandoc, Para, Str) behave like list-like containers. The items within these containers are the arguments passed to their constructors. You can use standard Python indexing, slicing, and assignment to access or modify their contents.

    Key container behaviors:

    • Random Access: Use doc[index] or doc[start:stop] to access elements. Use assignment doc[index] = new_element to modify them.
    • Length: len(element) returns the number of items in the container.
    • Equality: Elements can be compared using ==. Equality checks both the type and the contents (recursively).
    • Membership: Use the in operator to check if a specific element exists within a container.
    • Iteration: You can use a standard for elt in element: loop to iterate over the immediate children of a Pandoc element.
    import pandoc
    from pandoc.types import *
    
    # Example setup
    meta = Meta({})
    blocks = [Para([Str('Hello'), Space(), Str('world!')])]
    doc = Pandoc(meta, blocks)
    
    # Random access and modification
    print(doc[0])          # Meta({})
    print(doc[1][0][0])   # Str('Hello')
    
    doc[1] = [Para([Str('New')])]
    print(doc)
  5. Transform the AST using Lua filters

    master

    Lua filters use Pandoc's built-in Lua engine to transform the document. A Lua script should return a list of Lua filters. Each filter contains functions indexed by the name of the AST element (e.g., Header, Para) it should act upon.

    The pandoc Lua module is automatically loaded into the script's environment and provides helper functions for element creation.

    Pandoc searches for Lua filters in this order:

    1. A specified full or relative path.
    2. $DATADIR/filters.

    Lua filters are applied in the order specified on the command line, alongside JSON filters and citeproc processing.

    pandoc -L my_filter.lua input.md -o output.html
  6. Create block quotations in Pandoc Markdown

    master

    Block quotations are created by preceding one or more lines with a > character and an optional space.

    Syntax Styles

    • Standard: Every line in the block is preceded by >.
    • Lazy: The > character is only required on the first line of each block.

    Nesting and Indentation

    • Nesting: Block quotes can be nested by using multiple > characters (e.g., > > text).
    • Indented Code inside Quotes: To include an indented code block within a block quote, use five spaces after the > character to account for the marker and the optional space.

    Important Extension: blank_before_blockquote

    By default, Pandoc requires a blank line before a block quote (unless it is at the start of the document) to prevent accidental triggers from line-wrapped text. If this extension is enabled, a > immediately following text without a blank line will not be treated as a nested block quote.

    > This is a block quote.
    >
    > > A nested block quote.
    
    >     indented code block
  7. Interpolated Variables in Pandoc Templates

    master

    Variables are placed within matched delimiters.

    Naming Rules:

    • Must begin with a letter.
    • Can contain letters, numbers, _, -, and ..
    • Reserved Keywords (cannot be used as variable names): it, if, else, endif, for, sep, endfor.

    Behavior:

    • Simple values: Rendered verbatim (no automatic escaping).
    • Lists: Values are concatenated.
    • Maps: Renders the string true.
    • Other values: Renders an empty string.
    • Structured Data: Use periods to access nested fields (e.g., employee.salary accesses the salary field of the employee object).

    Example:

    $foo$
    $foo.bar.baz$
    ${foo_bar.baz-bim}
    $foo$
    $foo.bar.baz$
    $foo_bar.baz-bim$
    $ foo $
    ${foo}
    ${foo.bar.baz}
    ${foo_bar.baz-bim}
    ${ foo }
  8. Parse Images with `implicit_figures` extension

    master

    Images are parsed using the ![caption](url "title") syntax.

    With the implicit_figures extension, a standalone image like ![caption](/url/of/image.png) is parsed as an Image element where the caption is captured and the figure is implicitly created.

    >>> """
    ... ![la lune](lalune.jpg "Voyage to the moon")
    ... """
    ... # doctest: +PANDOC
        Pandoc(Meta(map()), [Para([Image((u'', [], []), [Str(u'la'), Space(), Str(u'lune')], (u'lalune.jpg', u'fig:Voyage to the moon'))])])
  9. Access document metadata and content via random access

    master

    A Pandoc object is structured as a sequence where the first element (index 0) is the Meta object and the subsequent elements (starting at index 1) are the document Block elements.

    To access metadata, you access the Meta object, then its internal dictionary. To access content, you access the list of blocks.

    Note: Direct index access is fragile and can raise KeyError or IndexError if the document structure differs from your expectation. It is recommended to use .get() on the metadata dictionary and perform isinstance() checks to ensure the structure matches your assumptions.

    # Accessing metadata 'date'
    meta = doc[0] # Pandoc(Meta, [Block])
    meta_dict = meta[0] # Meta({Text: MetaValue})
    date = meta_dict.get("date")
    
    # Accessing the first header
    blocks = doc[1] # [Block]
    header = blocks[0]
    # header is a Header(Int, Attr, [Inline])
    # header[2] contains the inlines
  10. Parse Links (Inline, Automatic, and Reference)

    master

    Pandoc supports multiple link styles:

    • Automatic Links: <http://google.com> or <email@address.com>.
    • Inline Links: [text](url "title").
    • Reference Links: [label][id] where [id]: url "title" is defined elsewhere.
    • Shortcut Reference Links: [label] where [label]: url is defined elsewhere (requires shortcut_reference_links extension).
    • Internal Links: [text](#anchor) or [text] with a corresponding [anchor]: #anchor definition.
    >>> """
    ... This is an [inline link](/url), and here's [one with
    ... a title](http://fsf.org "click here for a good time!"
    ... """
    ... # doctest: +PANDOC
        Pandoc(Meta(map()), [Para([Str(u'This'), Space(), Str(u'is'), Space(), Str(u'an'), Space(), Link((u'', [], []), [Str(u'inline'), Space(), Str(u'link')], u'/url'), Str(u','), Space(), Str(u'and'), Space(), Str(u"here's"), Space(), Str(u'[one'), Space(), Str(u'with'), SoftBreak(), Str(u'a'), Space(), Str(u'title](http://fsf.org'), Space(), Str(u'"click'), Space(), Str(u'here'), Space(), Str(u'for'), Space(), Str(u'a'), Space(), Str(u'good'), Space(), Str(u'time!')])])
  11. Understand the Pandoc document meta-model

    master

    Pandoc models every document as a tree of elements. A document is represented by a specific model, while the meta-model is the set of all valid documents (the hierarchy of types and rules that define how elements can be combined).

    To analyze, create, or transform documents, you must understand this hierarchy. The Python library implements the hierarchy originally defined in the pandoc-types Haskell package.

  12. Nesting and Breakable Spaces in Pandoc Templates

    master

    Pandoc provides directives to control text alignment and line breaking.

    • Nesting (^): Use the ^ directive to ensure subsequent lines of a multi-line variable are indented to align with the first line.
    • Breakable Spaces (~): By default, spaces in templates are not breakable. Wrap text in $~$ ... $~$ to allow the renderer to break lines at those spaces.
    • Automatic Nesting: If a variable is on its own line, preceded by whitespace and not followed by other text, multi-line values are automatically nested.

    Example:

    # Nesting
    $item.number$  $^$$item.description$
    
    # Breakable spaces
    $~$This long line may break.$~$
    $item.number$  $^$$item.description$ ($item.price$)
    
    $item.number$  $^$$item.description$ ($item.price$)
                   (Available til $item.sellby$.)
    
    $~$This long line may break if the document is rendered with a short line length.$~$