pandocfilters
raw JSON → 1.5.1 verified Tue May 12 auth: no python install: verified quickstart: stale
pandocfilters is a Python library that provides utilities for writing Pandoc filters. These filters manipulate Pandoc's Abstract Syntax Tree (AST) in its JSON representation between the reader (parser) and writer (output format). It is currently at version 1.5.1 and sees an active, though irregular, release cadence focused on maintenance and compatibility with Pandoc versions.
pip install pandocfilters Common errors
error ImportError: No module named pandocfilters ↓
cause The Python interpreter cannot find the 'pandocfilters' package, usually because it's not installed, or the environment where Pandoc is run doesn't have access to the installed package.
fix
Ensure pandocfilters is installed for the correct Python interpreter using
pip install pandocfilters or pip3 install pandocfilters. If using a virtual environment, activate it before installing and running Pandoc. error Error running filter /path/to/your_filter.py: Could not find executable /path/to/your_filter.py ↓
cause Pandoc was unable to locate or execute the specified Python filter script. This can happen if the path is incorrect, the script lacks executable permissions, or the shebang (`#!/usr/bin/env python3`) is wrong or missing.
fix
Verify the filter script's path is correct relative to where Pandoc is called, ensure the script has executable permissions (
chmod +x your_filter.py), and confirm the shebang points to a valid Python interpreter (e.g., #!/usr/bin/env python3). error Error running filter ...: Error in $: Failed reading: not a valid json value. ↓
cause The Python filter produced output that is not a valid JSON representation of Pandoc's Abstract Syntax Tree (AST), which Pandoc expects from filters. This often occurs due to malformed output or printing debug information to standard output.
fix
Inspect the Python filter for syntax errors, ensure that all debug prints go to
sys.stderr instead of sys.stdout, and that the filter consistently returns valid Pandoc AST objects (or None for no change, or a list of objects for replacement). error TypeError: 'str' object is not subscriptable ↓
cause This error frequently arises in `pandocfilters` when a filter function attempts to access a string value as if it were a list or dictionary (e.g., `value[0]`), typically when processing a `Str` element where `value` is just the string content, not a structured list.
fix
Carefully check the structure of the
value argument for each key type your filter handles. For 'Str' elements, value is a plain string. Access its content directly or use string methods. For other types (like 'Para', 'Header'), value is typically a list or tuple, and its internal structure (e.g., value[0], value[1]['c']) needs to be matched to the Pandoc AST specification for that element type. Warnings
breaking Python 2 support was officially dropped after `pandocfilters` version 1.5.0. If you are on Python 2, you must use `pandocfilters` <= 1.5.0. ↓
fix Upgrade to Python 3 or pin `pandocfilters` to version 1.5.0 or earlier.
breaking Compatibility with the underlying `pandoc` executable is critical and can break filters due to AST changes. Specific `pandocfilters` versions are tied to `pandoc` versions. ↓
fix Use `pandocfilters` <= 1.2.4 for `pandoc` versions 1.12-1.15. Use `pandocfilters` >= 1.3.0 for `pandoc` versions >= 1.16. `pandocfilters` 1.4.0 introduced compatibility with `pandoc` 1.17.3's new JSON format. Always check the `pandocfilters` README for the latest compatibility matrix.
gotcha The `get_filename4code` utility (used for generating filenames for code blocks, e.g., for images) by default creates temporary directories that are NOT automatically cleaned up. This can lead to an accumulation of files if not managed. ↓
fix Set the environment variable `PANDOCFILTER_CLEANUP` to any non-empty value (e.g., '1') before running your filter. This will cause temporary directories to be created in a temporary location and automatically removed upon filter exit.
gotcha Starting from version 1.5.0, the `examples/` directory is no longer included in the PyPI distribution (source or binary wheels). It is only available in the source repository on GitHub. ↓
fix If you rely on the examples, clone the GitHub repository (`http://github.com/jgm/pandocfilters`) directly instead of installing from PyPI, or browse the examples on GitHub.
gotcha Pandoc itself offers built-in Lua filters (since Pandoc 2.0) which do not require external language interpreters (like Python) and may offer better performance for some use cases. An alternative Python library, `panflute`, also exists, offering a more 'Pythonic' API. ↓
fix Consider if a Lua filter (using Pandoc's `--lua-filter` option) or `panflute` might be a better fit for your specific filtering needs, especially for new projects.
breaking `pandocfilters` expects valid JSON input from `pandoc` (typically via stdin). If `pandoc` does not output valid JSON, or outputs nothing, `pandocfilters` will fail with a `JSONDecodeError`. ↓
fix Ensure that `pandoc` is correctly configured to output JSON to the filter's stdin. This often means running `pandoc` with the `--to json` or `-t json` option and piping its output to the Python script, or calling the Python script directly as a filter where `pandoc` manages the I/O.
breaking The `pandocfilters` library expects a JSON representation of the Pandoc AST on `sys.stdin`. A `json.decoder.JSONDecodeError` at line 1, column 1 (char 0) indicates that no valid JSON was provided to the filter, often because the filter was run directly without `pandoc`, `pandoc` failed to execute, or `pandoc` produced non-JSON output (e.g., an error message) to `stdout`. ↓
fix Ensure your Python script is executed by `pandoc` using the `--filter` option (e.g., `pandoc input.md --filter ./your_filter.py -o output.html`), verify that `pandoc` is installed and accessible in your environment's PATH, and check `pandoc`'s output for errors if run standalone.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.02s 17.8M
3.10 alpine (musl) - - 0.02s 17.8M
3.10 slim (glibc) wheel 1.5s 0.01s 18M
3.10 slim (glibc) - - 0.01s 18M
3.11 alpine (musl) wheel - 0.02s 19.6M
3.11 alpine (musl) - - 0.03s 19.6M
3.11 slim (glibc) wheel 1.6s 0.02s 20M
3.11 slim (glibc) - - 0.02s 20M
3.12 alpine (musl) wheel - 0.02s 11.5M
3.12 alpine (musl) - - 0.02s 11.5M
3.12 slim (glibc) wheel 1.5s 0.02s 12M
3.12 slim (glibc) - - 0.02s 12M
3.13 alpine (musl) wheel - 0.02s 11.3M
3.13 alpine (musl) - - 0.02s 11.1M
3.13 slim (glibc) wheel 1.4s 0.02s 12M
3.13 slim (glibc) - - 0.03s 12M
3.9 alpine (musl) wheel - 0.02s 17.3M
3.9 alpine (musl) - - 0.02s 17.3M
3.9 slim (glibc) wheel 1.7s 0.02s 18M
3.9 slim (glibc) - - 0.02s 18M
Imports
- toJSONFilter
from pandocfilters import toJSONFilter - walk
from pandocfilters import walk - Str, Para, Header, Emph
from pandocfilters import Str, Para, Header, Emph
Quickstart stale last tested: 2026-04-24
#!/usr/bin/env python
"""
Pandoc filter to convert all regular text ('Str' elements) to uppercase.
Run with: pandoc input.md --filter ./caps_filter.py -o output.html
"""
from pandocfilters import toJSONFilter, Str
def caps(key, value, format, meta):
if key == 'Str':
return Str(value.upper())
if __name__ == "__main__":
toJSONFilter(caps)