Skip to main content

File conversion exchange for Linux: one command routes files to pandoc, ImageMagick, LibreOffice & more through an extensible converter registry.

Project description

fcx — File Conversion Exchange

fcx is a file conversion exchange for Linux — one command routes your files to the right backend (pandoc, ImageMagick, LibreOffice, Inkscape…) through an extensible converter registry.

PyPI

Motivation

Linux power users who regularly convert files face a fragmented landscape: pandoc for documents, convert for images, loffice --headless for Office files, pdftotext for PDF extraction, ffmpeg for audio. Each tool has a different interface, different flag conventions, and different merging semantics. Scripting across them requires memorising or looking up the invocation for every combination.

fcx provides a single, consistent command for all of these:

fcx report.pdf intro.pdf chapter.docx diagram.svg   # merge to pdf
fcx jpg:l2 photos/*.jpg                             # batch compress
fcx wav:16k recordings/*.mp3                        # audio normalisation

The tool is especially useful in Makefiles, shell scripts, and AI coding agent pipelines where you want one deterministic command to handle whatever input format you have.

Installation

pip3 install fcx

# or in an isolated environment
pipx install fcx

# upgrade
pip3 install --upgrade fcx

From source

git clone https://github.com/sjjsy/fcx.git
cd fcx
pip3 install -e .

Quick start

fcx chapter.md appendix.md          # → chapter.pdf (merge via pandoc)
fcx txt notes.md paper.pdf          # → notes.txt  (merge, pandoc + pdftotext)
fcx png *.svg                       # → per-file PNG (inkscape or ImageMagick)
fcx jpg:l1 photos/*.jpg             # compress in-place, backup to Trash
fcx jpg:crop:50x50 *.jpg            # center-crop 50% each axis, backup to Trash
fcx wav:16k recordings/*.mp3        # → per-file 16 kHz mono WAV
fcx -R                              # recover last in-place backup from Trash

System requirements

fcx itself requires only Python 3.8+ and docopt. Converters require their respective backend tools:

Tool Purpose Install
pandoc md/rst/html/docx → pdf/txt/md/rst/html apt install pandoc
ImageMagick image ↔ image, →pdf, in-place transforms apt install imagemagick
LibreOffice docx/pptx/xlsx/odt → pdf/txt apt install libreoffice
wkhtmltopdf html → pdf (also used by pandoc) apt install wkhtmltopdf
Inkscape svg → pdf/png apt install inkscape
pdflatex tex/tikz → pdf apt install texlive-latex-base
poppler-utils pdf → txt (pdftotext), pdf merge (pdfjam) apt install poppler-utils
ffmpeg audio/video → wav apt install ffmpeg
jpegoptim JPG lossy compression apt install jpegoptim
jpegtran JPG lossless optimisation apt install libjpeg-turbo-progs
optipng PNG optimisation apt install optipng

Only the tools needed for your conversions need to be installed. Use fcx -d to check what is available.

CLI reference

fcx — File Converter Exchange

Convert files to a different format or apply in-place transforms.
Inputs are merged (pdf, txt) or converted individually (img, same-format).

Usage:
  fcx (-d | --deps)    [EXT ...]
  fcx (-m | --methods) OEXT [OEXT ...]
  fcx (-i | --inputs)  OEXT [OEXT ...]
  fcx (-o | --outputs) IEXT [IEXT ...]
  fcx (-R | --recover) [EXT]
  fcx (-I | --init)    [TOOL]
  fcx [options] [ARGS ...]
  fcx -h | --help
  fcx --version

Options:
  -h --help        Show this screen.
  --version        Show version.
  -I --init        List built-in converter files or copy TOOL to user config dir.
  -d --deps        Check deps for all converters, or filter by EXT(s).
  -m --methods     List converters for each output OEXT.
  -i --inputs      List source formats that produce each output OEXT.
  -o --outputs     List output formats each input IEXT can produce.
  -R --recover     Restore most-recent fcx backup from Trash into CWD.
  -O --overwrite   Skip trash backup for same-format (in-place) transforms.
  -v --verbose     Stream live stdout/stderr from every shell command.
  --dry-run        Print commands without executing.

TARGET syntax:
  The first positional argument is treated as TARGET when it does not name an
  existing file on disk.  It takes the form  SPEC[:METHOD[:PARAMS]]  where:

    SPEC     Output extension (pdf, txt, png, jpg, wav, ...) or explicit output
             file path (report.pdf, out/notes.txt, ...).
             Omit entirely to default to "pdf".
    METHOD   Name or unique prefix of the converter to prefer, e.g.
             pandoc, loffice, wk, l1, crop.  Fuzzy prefix-matched against
             converter names; falls back to the next available converter.
    PARAMS   Parameter string passed verbatim to the converter function.
             Some converters require it (e.g. crop:50x50, annotate:Draft v2).

  Examples:
    pdf                  pdf:pandoc            jpg:l1
    jpg:crop:50x50       jpg:annotate:Draft v2 report.pdf:loffice
    wav:16k

Output file naming:
  SPEC is a path  → that is the output file.
  SPEC is an ext, merge mode (→pdf/txt)  → {first_input_stem}.{ext} in CWD.
  SPEC is an ext, per-file mode          → {each_input_stem}.{ext} in CWD.
  Same-format transform                  → input file path (in-place).

Trash backup (same-format transforms):
  Before in-place transforms, inputs are copied to:
    ~/.local/share/Trash/files/fcx_YYYYMMDD_HHMMSS_EXT/
  with a matching .trashinfo sidecar.  No external tools needed.
  Use -R / --recover to restore the most recent backup into CWD.
  Use -O / --overwrite to skip the backup entirely.

Examples:
  fcx report.pdf intro.pdf chapter.docx diagram.svg   # merge → pdf
  fcx pdf report.pdf intro.pdf chapter.docx           # same, explicit ext
  fcx txt notes.txt paper.pdf slides.pptx             # merge → txt
  fcx png *.svg                                       # batch svg → png
  fcx report.pdf:pandoc chapter.md appendix.md        # force pandoc
  fcx jpg:l1 photos/*.jpg                             # compress to trash
  fcx jpg:l1 -O photos/*.jpg                          # compress, no backup
  fcx jpg:crop:50x50 photos/*.jpg                     # center-crop 50%
  fcx jpg:annotate:Draft v2 *.jpg                     # annotate all
  fcx wav:16k recordings/*.mp3                        # audio → 16 kHz mono
  fcx -R                                              # recover last backup
  fcx -R jpg                                          # recover last jpg backup
  fcx -d                                              # check all deps
  fcx -d pdf                                          # check →pdf converter deps
  fcx -m pdf                                          # list all →pdf converters
  fcx -o docx                                         # what can docx become?
  fcx -i pdf                                          # what converts to pdf?
  fcx -I                                              # list built-in converter files
  fcx -I pandoc                                       # copy pandoc.py to user config dir

Registered converters

→ PDF (merge mode)

From formats Converter Backend Notes
pdf builtin-copy-pdf Passthrough / copy
jpg, png, gif, bmp, tiff, webp imagemagick convert Direct image→PDF
svg inkscape-pdf inkscape High-fidelity vector
svg imagemagick-svg-pdf convert Fallback
docx, odt, pptx, xls, xlsx, rtf, csv libreoffice loffice --headless
md, rst, html, xhtml, docx, rtf, txt pandoc-wk pandoc + wkhtmltopdf Best pandoc output
md, rst, html, tex, csv, … pandoc pandoc Fallback
html, xhtml, htm wkhtmltopdf wkhtmltopdf
tex, tikz pdflatex pdflatex Auto-runs biber/makeglossaries

→ TXT (merge mode)

From formats Converter Backend
txt, md, rst builtin-copy-txt
pdf pdftotext pdftotext
any above builtin-via-pdf chains →pdf, then pdftotext

→ Markup (merge mode)

To format Converter Backend
md pandoc-md pandoc
rst pandoc-rst pandoc
html pandoc-html pandoc

→ Image format conversion (per-file)

From To Converter Backend
svg pdf inkscape-pdf inkscape
svg png inkscape-png inkscape
svg jpg inkscape-jpg inkscape + convert
any image png imagemagick-to-img convert
any image jpg imagemagick-to-jpg convert

→ JPG in-place transforms (per-file, trash backup)

METHOD Deps Effect
l0 jpegtran Lossless optimise + progressive
l1 jpegoptim q 85
l2 jpegoptim, convert q 75; resize if > 2666 px
l3 jpegoptim, convert q 60; resize if > 800 px
luh convert Fit 3840×2160, q 90
lum convert Fit 3840×2160, q 60
lul convert Fit 3840×2160, q 40
lfh convert Fit 1920×1080, q 90
lfm convert Fit 1920×1080, q 60
lfl convert Fit 1920×1080, q 40
lm convert Fit 800×800, q 60
lb1 convert B&W document binarise
crop convert, identify Center-crop percentage per axis (PARAMS: WxH)
cropabs convert, identify Center-crop in pixels (PARAMS: WxH)
annotate convert, identify Overlay text label at bottom (PARAMS: text)
version convert, jpegtran, jpegoptim Creates ver/ with l0–l3 comparison set
montage convert Square-crop + assemble montage grid (PARAMS: cell_px)

→ PNG in-place transforms

METHOD Deps Effect
l0-png optipng Lossless optimise
l1-png optipng Aggressive lossless optimise
l2-png optipng, convert Resize if > 2666 px
l3-png optipng, convert Resize if > 800 px
lb1-png convert B&W document binarise
crop-png convert, identify Center-crop percentage (PARAMS: WxH)
cropabs-png convert, identify Center-crop in pixels (PARAMS: WxH)
annotate-png convert, identify Overlay text label

→ WAV (per-file)

From formats Converter Backend Effect
mp3, m4a, ogg, flac, aac, opus, wma, wav, mp4, … ffmpeg-16k ffmpeg 16 kHz mono WAV

Checking what is available

fcx -d                   # all converters and their deps
fcx -d pdf               # deps for →pdf converters only
fcx -m pdf               # list all →pdf converters, which would be selected
fcx -m jpg               # list all →jpg converters
fcx -i pdf               # what input formats can produce pdf?
fcx -o docx              # what output formats can docx produce?

Extending fcx

Converters live in CONVERTERS lists inside Python files. Three layers are merged at startup — later layers win for same-named converters; unique names coexist with user/system versions listed first:

1. built-in   fcx/converters/*.py         (ships with fcx)
2. system     /etc/xdg/fcx/converters/*.py
3. user       ~/.config/fcx/converters/*.py   ← highest priority

Add a custom converter

Copy a built-in converter file to your user config dir:

fcx -I pandoc              # copies pandoc.py to ~/.config/fcx/converters/pandoc.py
fcx -I                     # list all built-in converter files

Then edit the copy. Delete the file to revert to the built-in.

Write one from scratch

Create ~/.config/fcx/converters/mytools.py:

from pathlib import Path
from typing import List, Optional
from fcx.core import Converter, run

def _my_converter(srcs: List[Path], dst: Path, params: Optional[str]) -> None:
    run(["mytool", "--output", str(dst)] + [str(s) for s in srcs])

CONVERTERS = [
    Converter(
        name="mytool",
        from_formats=("md",),
        to_format="pdf",
        deps=["mytool"],
        params=None,
        fn=_my_converter,
        mode="merge",     # "merge" | "per-file" | "in-place" | "auto"
    ),
]

Verify: fcx -d pdf and fcx -m pdf.

Converter dataclass

@dataclass
class Converter:
    name: str                 # matched by METHOD prefix in TARGET
    from_formats: tuple       # input extensions (lowercase, no dot)
    to_format: str            # output extension
    deps: list                # binary names checked on PATH
    params: str | None        # human-readable PARAMS description, or None
    fn: Callable              # fn(srcs: list[Path], dst: Path, params: str | None)
    mode: str = "auto"        # dispatch mode (see above)

Dispatch mode

mode behaviour
"auto" merge if to_format in (pdf, txt); in-place if to==from; else per-file
"merge" all inputs passed to fn at once, one output
"per-file" fn called once per input, no trash backup
"in-place" fn called once per input, trash backup before first call

Verbose and dry-run

fcx -v jpg:l1 photo.jpg     # stream live output from jpegoptim
fcx --dry-run pdf *.md      # print commands without running them

Examples

# Document conversion
fcx report.pdf chapter.md appendix.md      # merge md → pdf
fcx txt notes.pdf slides.pptx              # merge to txt
fcx html document.docx                     # docx → html via pandoc

# Image conversion
fcx png *.svg                              # batch svg → png (inkscape)
fcx jpg diagram.svg                        # svg → jpg

# In-place image compression (all backed up to Trash first)
fcx jpg:l1 photos/*.jpg                    # compress to q85
fcx jpg:l2 photos/*.jpg                    # q75, resize if > 2666px
fcx jpg:l3 -O photos/*.jpg                 # q60, no backup (--overwrite)
fcx jpg:luh portraits/*.jpg                # fit 4K UHD, q90

# In-place image transforms
fcx jpg:crop:75x75 thumbnails/*.jpg        # center-crop to 75%
fcx jpg:cropabs:800x800 pics/*.jpg         # center-crop to 800×800px
fcx jpg:annotate:Draft *.jpg               # overlay label "Draft"
fcx jpg:lb1 scans/*.jpg                    # binarise to B&W document

# PNG optimisation
fcx png:l1-png images/*.png                # aggressive lossless optimise
fcx png:crop-png:80x80 icons/*.png         # center-crop PNGs

# Comparison sets and montage
fcx jpg:version photo.jpg                  # creates ver/ with l0–l3 comparison
fcx jpg:montage *.jpg                      # assemble 300×300 montage grid

# Audio
fcx wav:16k recordings/*.mp3               # 16 kHz mono WAV for ASR
fcx wav:16k interview.m4a                  # single file

# Dependency check
fcx -d                                     # all converters
fcx -d jpg                                 # only jpg-related converters

# Discovery
fcx -m pdf                                 # what converters exist for →pdf?
fcx -i pdf                                 # what can be converted to pdf?
fcx -o docx                                # what can docx become?

# Recovery
fcx -R                                     # restore last backup
fcx -R jpg                                 # restore last jpg backup

Contributing

Fork the repository and open a pull request. Adding converters for new backend tools is the most welcome contribution — each converter file is self-contained and easy to write.

License

GNU Affero General Public License v3.0 — see LICENSE.


Related projects

fcx sits at the intersection of document conversion and image processing automation. The tables below place it in context.

Document conversion backends

These are the system tools that fcx dispatches to. Each has a different sweet spot; fcx selects the best available one automatically.

Tool License Best for Used in fcx
pandoc GPL-2 Universal markup converter; md/rst/html/docx → pdf/html/txt and 50+ formats Yespandoc, pandoc-wk
LibreOffice MPL-2 Office formats (docx/pptx/xlsx/odt) headless conversion Yeslibreoffice (via loffice --headless)
wkhtmltopdf LGPL-3 HTML → PDF with full CSS/JS rendering (WebKit engine) Yeswkhtmltopdf
ImageMagick Apache-2 Image ↔ image, raster → PDF, compositing Yesconvert, identify, montage
Inkscape GPL-3 SVG → PDF/PNG with full vector fidelity Yesinkscape --export-type
pdflatex / TeX Live Mixed/Free TeX → PDF with bibliography and glossary management Yespdflatex, biber, makeglossaries
poppler-utils GPL-2 PDF text extraction (pdftotext), PDF merge (pdfjam) Yespdftotext, pdfjam
ffmpeg LGPL-2.1 Audio/video format conversion Yesffmpeg-16k
jpegoptim GPL-2 Lossy JPG compression with quality targets Yesl1l3 converters
jpegtran BSD Lossless JPG transform and optimisation Yesl0 converter
optipng zlib/libpng Lossless PNG compression Yesl0-pngl3-png
Weasyprint BSD HTML → PDF via Python (no Qt/WebKit); CSS Paged Media No — alternative to wkhtmltopdf
unoconv GPL-2 LibreOffice UNO bridge; similar to loffice --headless No — superseded by loffice --headless

Python document conversion libraries

Pure Python or wrapper libraries that avoid shelling out. fcx prefers system tools for flexibility but these are useful when you need embedded conversion.

Library License Stars Best for
pypandoc MIT 1.3k Python wrapper around pandoc; supports all pandoc formats
docx2pdf MIT 2.1k DOCX → PDF on macOS (Word) / Linux (LibreOffice)
img2pdf LGPL-3 1.0k Lossless image → PDF; preserves original pixels without re-encoding
pdf2image MIT 1.8k PDF → PIL Image objects via poppler
python-pptx MIT 2.6k Read/write PPTX; no built-in PDF export
pymupdf AGPL-3 / commercial 4.8k High-speed PDF/XPS/EPUB rendering, extraction, annotation
weasyprint BSD 7.1k HTML/CSS → PDF in Python; CSS Paged Media support

Batch file conversion tools

CLI and GUI tools that wrap multiple conversion backends — the category closest to fcx itself.

Tool Type Platform License Formats Notes
fcx (this) CLI Linux AGPL-3 docs, images, audio Extensible registry; in-place transforms; trash backup; scriptable
fileConverter GUI Windows GPL-3 images, audio, video, docs Right-click shell extension; uses ffmpeg/ImageMagick
unoconv CLI Linux/macOS GPL-2 office formats only LibreOffice UNO bridge; no longer actively maintained
pandoc CLI Any GPL-2 markup/docs only The gold standard for document conversion; no images or audio
Converseen GUI Linux/Windows GPL-3 images only Qt/ImageMagick batch image converter
Kramdown-AsciiDoc CLI Any MIT md → asciidoc Single format pair, deep conversion fidelity

Image optimisation CLIs

Tools focused on reducing image file size. fcx wraps these under a consistent interface with trash backup.

Tool License Algorithm In fcx
jpegoptim GPL-2 Progressive JPEG; quality targets; strips metadata Yesl1, l2, l3
jpegtran BSD Lossless DCT operations; progressive scan Yesl0
optipng zlib Lossless PNG deflate optimisation Yesl0-pngl3-png
pngquant GPL-3 Lossy PNG palette quantisation (often 60–80% savings) No — lossy; would fit a future l1-png lossy variant
oxipng MIT Multi-threaded lossless PNG (Rust); faster than optipng No — could replace optipng as a future built-in
Squoosh CLI Apache-2 WASM-based multi-format image optimisation No — Node.js dependency
ImageOptim-CLI MIT Orchestrates multiple tools (jpegtran, pngquant, …) No — macOS-native tools

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fcx-0.1.4.tar.gz (30.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fcx-0.1.4-py3-none-any.whl (28.7 kB view details)

Uploaded Python 3

File details

Details for the file fcx-0.1.4.tar.gz.

File metadata

  • Download URL: fcx-0.1.4.tar.gz
  • Upload date:
  • Size: 30.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for fcx-0.1.4.tar.gz
Algorithm Hash digest
SHA256 fe85c86a1072fa203154bbf08174273073b27a1c5f4a15ae73deab92081878d6
MD5 fb7071c5278a40406c54da143f2c6fe1
BLAKE2b-256 574be7c4d69e0d9f8b4c3c36914eeea9a81246d06a964cc4568a9ca04c6de166

See more details on using hashes here.

File details

Details for the file fcx-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: fcx-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 28.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for fcx-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 08b126805711e58cbd15653aa6452f309677494bfe184861641f14ab06827e56
MD5 951e464f98ce9e1c5d4c48acbea7535b
BLAKE2b-256 52cc40c7c92a153632d80d958bd104e148c4cfd5bb7e992f3160f6a3614d1ef0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page