{"id":22068787,"url":"https://github.com/dsanson/termpdf","last_synced_at":"2025-07-24T07:31:01.173Z","repository":{"id":2020143,"uuid":"44062011","full_name":"dsanson/termpdf","owner":"dsanson","description":"barebones graphical pdf/djvu/cbr/image viewer that works inside iTerm2 2.9+ and Kitty","archived":false,"fork":false,"pushed_at":"2024-01-31T12:16:41.000Z","size":21556,"stargazers_count":632,"open_issues_count":10,"forks_count":25,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-04-28T00:18:33.049Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dsanson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-11T17:24:18.000Z","updated_at":"2024-04-02T17:27:07.000Z","dependencies_parsed_at":"2022-09-24T08:50:36.186Z","dependency_job_id":null,"html_url":"https://github.com/dsanson/termpdf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsanson%2Ftermpdf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsanson%2Ftermpdf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsanson%2Ftermpdf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsanson%2Ftermpdf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsanson","download_url":"https://codeload.github.com/dsanson/termpdf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227421331,"owners_count":17775010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-30T20:04:21.327Z","updated_at":"2024-11-30T20:07:02.565Z","avatar_url":"https://github.com/dsanson.png","language":"Shell","funding_links":[],"categories":["Shell","others"],"sub_categories":[],"readme":"termpdf.py\n=========\n\nI decided to try again, in python, using pymupdf as a backend, and dropping support for iTerm2 and focusing just on kitty's more robust graphics support. The preliminary results are snappier, and it should be easy to add more powerful features:\n\n\u003chttps://github.com/dsanson/termpdf.py\u003e\n\ntermpdf\n=======\n\n`termpdf` is a barebones graphical PDF (and DJVU and TIFF and CBR and\nCBZ and JPG and PNG and GIF and BMP) viewer that runs in your terminal.\n\nRight now, it runs in\n\n-   [iTerm](https://iterm2.com/) 2.9 or later\n-   [kitty](https://github.com/kovidgoyal/kitty)\n\nAnd has experimental support for\n\n-   [libsixel](https://github.com/saitoha/libsixel)\n\nIt is a ridiculous hack---a bash script wrapped around some special terminal\nescape codes and a bunch of command line tools. But it works well enough for me to be useful.\n\nScreenshots\n===========\n\nRunning in Kitty:\n\n![Screenshot in Kitty](screenshot_kitty.png)\n\nRunning in iTerm:\n\n![Screenshot in iTerm](screenshot_iterm.png)\n\nRequirements\n============\n\nLet me start with the tl;dr instructions. \n\nMake sure you are running a recent version of Kitty or iTerm.\n\nInstall `terminal dimensions`:\n\n~~~\ngit clone https://github.com/dsanson/terminal_dimensions\ncd terminal_dimensions\ngcc terminal_dimensions.c -o terminal_dimensions\nmv terminal_dimensions /usr/local/bin\n~~~\n\nInstall dependencies. On OSX,\n\n```.bash\nbrew install poppler djvulibre libtiff unrar imagemagick bash\n```\n\nOn Debian,\n\n```.bash\napt install ghostscript bc libtiff5 unrar imagemagick poppler-utils\n```\nOn Archlinux and its derivatives\n\n```.bash\npacman -S bc poppler djvulibre ghostscript libtff unrar imagemagick\n```\n\ntermpdf is also available in the [Arch User Repository](https://aur.archlinux.org/packages/termpdf-git/). You can install it using your favorite AUR helper program, which should also handle the dependencies, including `terminal_dimensions`. For example, using yay:\n\n```bash\nyay -S termpdf-git\n```\n\nDownload the `termpdf` and `tpdfc` scripts, make them executable, and put them in your path:\n\n```.bash\ngit clone https://github.com/dsanson/termpdf\ncd termpdf\nchmod u+x termpdf\nchmod u+x tpdfc\ncd /usr/local/bin\nln -s /path/to/termpdf\nln -s /path/to/tpdfc\n```\n\nTerminal Emulator\n-----------------\n\nYou will need iTerm version 2.9 or later, or Kitty, version greater than 0.6.1,\nor, if you want to play around, a terminal with sixel support. iTerm support\nhas been around for awhile. It should be pretty stable if a bit slow. Kitty\nsupport is new and significantly faster than iTerm---especially if you use the\n`terminal_dimensions` helper app.\n\nTo use with Kitty, be sure that the `kitty` executable is in your path.\n\nA previous version of the script tried to support X11 using `w3mimgdisplay`.\nThat got complicated and it didn't work, so I removed it. But recent changes\nto the code probably make it easier to implement.\n\nterminal_dimensions\n-------------\n\nThis is a tiny command line tool written in C that reports terminal\ndimensions, both in character cells and in pixels, e.g.,\n\n~~~\n$ terminal_dimensions\n141 43 2538 1548\n~~~\n\nThis is helpful, because standard cli tools don't report pixel dimensions. But\nin many emulators, including iTerm, the pixel dimensions will be misreported as 0 and 0:\n\n~~~\n$ terminal_dimensions\n141 43 0 0\n~~~\n\nThis is too bad, because pixel dimensions are super helpful! Install this, and\nimage rendering in Kitty is *much* faster. Also, you will need this if you\nwant to play around with the `sixel` support.\n\n~~~\n$ git clone https://github.com/dsanson/terminal_dimensions\n$ cd terminal_dimensions\n$ gcc terminal_dimensions.c -o terminal_dimensions\n$ mv terminal_dimensions /usr/local/bin\n~~~\n\nPoppler, djvulibre, libtiff, unrar, imagemagick, ghostscript\n-------\n\nThe script uses `pdfseparate` and `pdfinfo`, from Poppler to manipulate PDFs, `ddjvu` and `djvudump`, from DJVULibre, to manipulate DJVU files, and `tiffutil` and `tiffinfo`, to manipulate TIFF files. It uses `unrar` and `unzip` to unpack CBR and CBZ files. It uses ImageMagick's `convert` and `identify`. And it uses Ghostscript to convert PDFs to PNGS, because it is faster, and offers more control, than Poppler's `pdfcairo`.\n\nOn OS X, you can install all these things by running:\n\n    $ brew install poppler djvulibre libtiff unrar imagemagick\n\nBash 4.x\n--------\n\nIf you run the script from Bash 4.x, it supports marks. OS X still ships with Bash 3.x, so,\n\n    $ brew install bash\n\nLibreOffice\n-----------\n\nI've added basic support for viewing Microsoft Office (docx, xlsx, pptx) and\nLibreOffice (odt, ods, odp) files. The script converts them to PDF using\nLibreOffice, and then displays the resulting PDF. For this to work, you'll\nneed to have a copy of LibreOffice installed in your `/Applications` folder.\n\nTODO: As written, this probably only works on OS X.\n\n\nLibsixel\n--------\n\nIf you want to try out the experimental sixel support, be sure you have `terminal_dimensions` installed. You also need to install \n\n-   [libsixel](https://github.com/saitoha/libsixel)\n\nand make sure that the `img2sixel` command is in your path. Then try:\n\n```\n$ termpdf -sixel \u003cfile\u003e\n$ termpdf -sixel \u003cdirectory\u003e\n```\n\nHere is a screenshot of the best results I can get using a version of xterm built with sixel support on OS X:\n\n![sixel screenshot](screenshot_xterm.png)\n\nInstallation\n============\n\n`termpdf` and `tpdfc` are bash scripts. Put them somewhere in your path and make sure they have\nthe appropriate permissions (i.e., `chmod u+x termpdf`).\n\n\nUsage\n=====\n\n```.bash\n$ termpdf -h\ntermpdf \u003coptions\u003e \u003cfile/directory\u003e\n  -d n, --depth N                    how deep to search directories for images\n  -sixel                             use libsixel to (badly) display graphics     \n  -kitty                             force using kitty to display graphics\n  -iterm                             force using iterm to display graphics\n  -k                                 list keyboard shortcuts\n  -h, --help                         view this help\n```\n\n`\u003cfile/directory\u003e` should be a file in one of the supported formats or a path\nto a directory containing images.\n\nFormat is determined by extension. Supported multipage are formats: \n\n    PDF, DJVU, TIF, CBR, CBZ, CBT\n\nSupported single image formats are\n\n    JPG, JPEG,  PNG, GIF, BMP, SVG, PBM, PNM, ICO, PCD, PICT, PES, PSD, TTF, XCF\n\nIt should be trivial to add support for any format that Imagemagick\nsupports that doesn't require special handling.\n\nDirectories, along with common archive formats (ZIP, RAR, and TAR), are\ntreated as multipage documents. Directories are searched recursively by\n`find`, and displayed in the order found. The `--depth` option specifies the\ndepth of `find`'s recursive search.\n\nBy default, `termpdf` uses Kitty's image rendering if it is available, and\notherwise tries to use iTerm's image rendering. You can override this behavior\nby specifying one of `-sixel`, `-kitty`, or `-iterm`.\n\nKeyboard Shortcuts\n------------------\n\n```bash\n$ termpdf -k\nKeyboard shortcuts:\n\n  enter/space:                   forward one page\n  [n]k/j:                        forward or back [n] pages\n  [n]G:                          go to page [n]\n  G:                             go to last page\n  gg:                            go to first page\n  /\u003cquery\u003e:                      search text for \u003cquery\u003e\n  [n]n:                          go to next search result\n  [n]N:                          go to previous search result\n  [n]p:                          print [n copies of] document\n  [n]y:                          yank [n] pages forward and save as pdf\n  yy:                            yank current page and save as pdf\n  [n]+:                          zoom in (currently broken)\n  [n]-:                          zoom out (currently broken)\n  =:                             fit screen (currently broken)\n  c:                             crop margins \n  m[r]:                          store current page in register [r]\n  '[r]:                          go to page stored in register [r]\n  g'[r]:                         go to to page in register [r] \n  y'[r]:                         yank from current page to mark and save as pdf\n  r:                             refresh display\n  R:                             reload document\n  [n]r:                          rotate [n] degrees (0=0;1=90;2=180;3=270)\n  t:                             view entire document as text in less\n  T:                             view current page as text in less\n  M:                             remake document\n  a:                             annotate in split pane\n  q:                             quit\n  h:                             view this help\n  u:                             user definable function\n```\n\nThese commands are all set by the `keys()` function. You can override them in the config file if you\nwant.\n\nThere is also mostly undocumented support for `:` style commands, e.g.,\n\n  :first                                go to first page\n  :last                                 go to last page\n  :goto 20                              go to page 20\n  :print \u003ccopies\u003e \u003cpage-range\u003e\n  :yank \u003cpage-range\u003e\n  :search \u003cquery\u003e\n  :next \u003ccount\u003e\n  :gui                                  open the document in your default viewer\n  :text all\n  :text page\n  :refresh\n  :reload\n  :rotate 90\n  :crop\n  :marks                                list marks\n  :quit                                 quit\n\nThis is mostly useless from within the software, because bash's `read` command\ndoesn't support customizable autocompletion when called within scripts. But it\nis useful when using `tpdfc`.\n\n# Controlling `termpdf` using `tpdfc`\n\nYou can issue `:` style commands to a running instance of `termpdf` using the command\n`tpdfc`. For example,\n\n    $ tpdfc goto 5\n\nwill flip to page 5. If more than one instance of `termpdf` is running, you\ncan specify the instance you wish to control either by PID or just by number:\n\n    $ tpdfc -n 2 goto 5\n    $ tpdfc -p \u003cPID\u003e goto 5\n\nTo list all available instances,\n\n    $ tpdfc -l\n\n# Configuration files\n\nYou can put any commands you want into `$HOME/.config/termpdf/config`, which\nis sourced during the setup process. This allows you, among other\nthings, to override the key mappings and tweak the print settings.\n\nYou can also put commands in `$HOME/.config/termpdf/exithook`, which will be\nsourced before the script exits. \n\n# Known issues\n\n-   Earlier versions of the script worked well with tmux on iTerm. The current version does not. I'm not sure why.\n\n-   The make command only works if you have a Makefile in the same\ndirectory as the PDF. It would be nice to support a configurable make command.\n\n-   There is no robust error checking. This is just a bash script. So occasionally\nit will just crash or fart or do something unexpected.\n\n# TODO\n\n-   rewrite in real language (using ncurses?).\n-   rewrite kitty support using escape codes instead of `kitty icat`\n    \n# Similar Projects\n\nEmacs users already know about\n[pdf-tools](https://github.com/politza/pdf-tools). It would be amazing to\nreplicate its level of functionality for a pdf viewer in the tmux+vim\nworkflow.\n\n\n-   [fbpdf](http://repo.or.cz/fbpdf.git): a pdf viewer for the framebuffer\n    with vim-like navigation.\n-   [jfbview](https://seasonofcode.com/pages/jfbview.html): another pdf viewer for\n    the framebuffer.\n-   [imgcat](https://iterm2.com/images.html): the sample imgcat implementation\n    from the developer of iTerm2. Works in tmux. Doesn't provide control over\n    width and height of image.\n-   [term-img](https://github.com/sindresorhus/term-img): javascript node\n    library for viewing images in iTerm2. Also offers a command line tool.\n    Doesn't work in tmux.\n-   [imgcat-cli](https://github.com/egoist/imgcat-cli): a javascript node\n    image viewer for iTerm2 (fork of term-img). Doesn't work in tmux.\n-   [termimg](https://github.com/frnsys/termimg): uses `w3mimgdisplay`.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsanson%2Ftermpdf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsanson%2Ftermpdf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsanson%2Ftermpdf/lists"}