commit 8f358334d7a566bd5f10e07feb97f8bd0e4b71e0 Author: Michael Murtaugh Date: Thu Mar 10 14:03:01 2022 +0100 notebook + font diff --git a/OSP-DIN.ttf b/OSP-DIN.ttf new file mode 100644 index 0000000..d30ca55 Binary files /dev/null and b/OSP-DIN.ttf differ diff --git a/PythonPDFPostits.ipynb b/PythonPDFPostits.ipynb new file mode 100644 index 0000000..66d5cf9 --- /dev/null +++ b/PythonPDFPostits.ipynb @@ -0,0 +1,1489 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4014e69f-fb17-445e-bf02-a5e226979574", + "metadata": { + "tags": [] + }, + "source": [ + "## Scripted PDF generation with reportlab\n", + "\n", + "Reportlab is a python library that can generate PDFs. It provides a \"canvas\" object that gives very precise controls to create/draw on pages of a PDF. There are lots of drawing commands that you can use see [the docs in the RL userguide](\n", + "https://www.reportlab.com/docs/reportlab-userguide.pdf#page=11)." + ] + }, + { + "cell_type": "markdown", + "id": "e6ab8442-b778-41d1-ac9d-49c26e799345", + "metadata": { + "tags": [] + }, + "source": [ + "### Draw a grid\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "1366adcc-fbb7-4bc6-80f7-86dda20dbccf", + "metadata": {}, + "outputs": [], + "source": [ + "from reportlab.pdfgen.canvas import Canvas\n", + "from reportlab.lib.pagesizes import A4, A0\n", + "from reportlab.lib.units import inch, cm, mm\n", + "import sys\n", + "from reportlab.pdfbase.ttfonts import TTFont, pdfmetrics" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "9f72bd73-c2e2-4b49-8f48-378fed3fa11a", + "metadata": {}, + "outputs": [], + "source": [ + "# Normally you can use a built in page size like A0, A4\n", + "# c = Canvas(\"grid.pdf\", pagesize=A0, bottomup=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "8649fc44-18e8-4869-8c53-aec397b3a5d4", + "metadata": {}, + "outputs": [], + "source": [ + "# But we make a custom size with pagew & pageh\n", + "# nb the bottomup option this makes 0,0 the top left of page as you might expect (but it isn't the default)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "21d33c4e-93c3-4ba3-9019-5abf9d334816", + "metadata": {}, + "outputs": [], + "source": [ + "pagew, pageh = 75*mm, 75*mm\n", + "c = Canvas(\"grid.pdf\", pagesize=(pagew, pageh), bottomup=0)" + ] + }, + { + "cell_type": "markdown", + "id": "53cfea16-a6f7-4f3c-b58c-9df93808390e", + "metadata": {}, + "source": [ + "and don't forget about the question mark to get docs" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "0551a95c-6739-4986-8714-e82a48bc8a8d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mSignature:\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDocstring:\u001b[0m\n", + "draw a line segment from (x1,y1) to (x2,y2) (with color, thickness and\n", + "other attributes determined by the current graphics state).\n", + "\u001b[0;31mFile:\u001b[0m ~/.local/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py\n", + "\u001b[0;31mType:\u001b[0m method\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "c.line?" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "f24545dc-cb32-4097-a87d-44a323997d83", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mSignature:\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetLineWidth\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDocstring:\u001b[0m \n", + "\u001b[0;31mFile:\u001b[0m ~/.local/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py\n", + "\u001b[0;31mType:\u001b[0m method\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "c.setLineWidth?" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "2d84fe70-de02-4dcd-9209-edb2c72c5218", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2383.937007874016, 3370.393700787402)\n", + "21.259842519685044\n" + ] + } + ], + "source": [ + "colw = pagew/10\n", + "print (A0)\n", + "print (colw)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "f57e7e6a-c44c-4c78-9854-e1e74c6441ae", + "metadata": {}, + "outputs": [], + "source": [ + "for x in range(10):\n", + " c.line(x*colw, 0, x*colw, pageh)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "e04e1107-5eaa-4f25-9da9-c166463efd3c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "21.259842519685044\n" + ] + } + ], + "source": [ + "colh = pageh/10\n", + "print (colh)\n", + "for y in range(10):\n", + " c.line(0, y*colh, pagew, y*colh)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "ca2afe5f-bbbc-4308-993a-e8d93d85ad17", + "metadata": {}, + "outputs": [], + "source": [ + "c.showPage() # always shave a page to finish it...\n", + "c.save() # finally writes the PDF" + ] + }, + { + "cell_type": "markdown", + "id": "ce4e9a55-5ba9-4728-9013-af280369fe1a", + "metadata": {}, + "source": [ + "### Make a PDF with blank pages" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "4d27924b-9527-44e0-b74f-65427b7e6751", + "metadata": {}, + "outputs": [], + "source": [ + "from reportlab.pdfgen.canvas import Canvas\n", + "from reportlab.lib.pagesizes import letter, A4\n", + "from reportlab.lib.units import mm, cm\n", + "# from reportlab.pdfbase.ttfonts import TTFont, pdfmetrics\n", + "\n", + "size = (75*mm, 75*mm)\n", + "pages=10\n", + "c = Canvas(\"blank.pdf\", pagesize=size)\n", + "for i in range(pages):\n", + " # c.setPageSize(size)\n", + " c.showPage()\n", + "c.save()" + ] + }, + { + "cell_type": "markdown", + "id": "17d5bbe7-c955-4a97-8922-cd97be8733de", + "metadata": {}, + "source": [ + "## Make simple text titles\n", + "\n", + "Report lab's canvas doesn't do word wrapping / line breaking, but if you are OK with manually placing type you can use it." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "fd519538-dc94-4845-a25f-8fffa93828ec", + "metadata": {}, + "outputs": [], + "source": [ + "from reportlab.pdfbase.ttfonts import TTFont" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "04b984ee-8fe7-46f4-8b67-d2f199b50033", + "metadata": {}, + "outputs": [], + "source": [ + "from reportlab.pdfgen.canvas import Canvas\n", + "from reportlab.lib.pagesizes import letter, A4\n", + "from reportlab.lib.units import mm, cm\n", + "# from reportlab.pdfbase.ttfonts import TTFont, pdfmetrics\n", + "\n", + "titles = (\"One\", \"Two\", \"Three\", \"Four\")\n", + "\n", + "size = (75*mm, 75*mm)\n", + "pages=10\n", + "\n", + "pdfmetrics.registerFont(TTFont('DIN', 'OSP-DIN.ttf'))\n", + "\n", + "c = Canvas(\"titles.pdf\", pagesize=size, bottomup=0)\n", + "for title in titles:\n", + " c.setFont('DIN', 32)\n", + " c.drawString(5*mm, 15*mm, title) # nb the 2nd number is the distance (from top) to the baseline of the text\n", + " # c.setPageSize(size)\n", + " c.showPage()\n", + "c.save()" + ] + }, + { + "cell_type": "markdown", + "id": "b49c0bb2-b93b-4803-8ee8-a0335a1b3e04", + "metadata": { + "tags": [] + }, + "source": [ + "### Convert a folder of images to PDF\n", + "\n", + "Let's download some (public domain) game tiles from Kenney.nl" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "4fdf8977-3dd8-4dc7-a360-92cd0a0c14e5", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2022-03-10 13:44:05-- https://www.kenney.nl/content/3-assets/14-monochrome-rpg/kenney_monochromerpg.zip\n", + "Resolving www.kenney.nl (www.kenney.nl)... 149.210.216.123\n", + "Connecting to www.kenney.nl (www.kenney.nl)|149.210.216.123|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 387381 (378K) [application/zip]\n", + "Saving to: ‘kenney_monochromerpg.zip’\n", + "\n", + "kenney_monochromerp 100%[===================>] 378.30K 1.22MB/s in 0.3s \n", + "\n", + "2022-03-10 13:44:05 (1.22 MB/s) - ‘kenney_monochromerpg.zip’ saved [387381/387381]\n", + "\n" + ] + } + ], + "source": [ + "!wget https://www.kenney.nl/content/3-assets/14-monochrome-rpg/kenney_monochromerpg.zip" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "7c824ff2-ab03-43e8-9472-9a01b3172d9d", + "metadata": { + "collapsed": true, + "jupyter": { + "outputs_hidden": true + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Archive: kenney_monochromerpg.zip\n", + " creating: kenney/Dot Matrix/\n", + " creating: kenney/Dot Matrix/Sprites/\n", + " inflating: kenney/Dot Matrix/Sprites/character0.png \n", + " inflating: kenney/Dot Matrix/Sprites/character1.png \n", + " inflating: kenney/Dot Matrix/Sprites/character2.png \n", + " inflating: kenney/Dot Matrix/Sprites/character3.png \n", + " inflating: kenney/Dot Matrix/Sprites/enemy0.png \n", + " inflating: kenney/Dot Matrix/Sprites/enemy1.png \n", + " inflating: kenney/Dot Matrix/Sprites/enemy2.png \n", + " inflating: kenney/Dot Matrix/Sprites/heart0.png \n", + " inflating: kenney/Dot Matrix/Sprites/heart1.png \n", + " inflating: kenney/Dot Matrix/Sprites/heart2.png \n", + " inflating: kenney/Dot Matrix/Sprites/item0.png \n", + " creating: kenney/Dot Matrix/Tilemap/\n", + " inflating: kenney/Dot Matrix/Tilemap/tilemap.png \n", + " inflating: kenney/Dot Matrix/Tilemap/tilemap_packed.png \n", + " creating: kenney/Dot Matrix/Tiles/\n", + " inflating: kenney/Dot Matrix/Tiles/tile_0000.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0001.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0002.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0003.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0004.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0005.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0006.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0007.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0008.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0009.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0010.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0011.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0012.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0013.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0014.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0015.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0016.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0017.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0018.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0019.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0020.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0021.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0022.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0023.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0024.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0025.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0026.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0027.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0028.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0029.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0030.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0031.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0032.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0033.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0034.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0035.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0036.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0037.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0038.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0039.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0040.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0041.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0042.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0043.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0044.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0045.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0046.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0047.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0048.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0049.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0050.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0051.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0052.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0053.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0054.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0055.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0056.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0057.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0058.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0059.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0060.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0061.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0062.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0063.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0064.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0065.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0066.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0067.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0068.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0069.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0070.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0071.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0072.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0073.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0074.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0075.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0076.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0077.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0078.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0079.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0080.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0081.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0082.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0083.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0084.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0085.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0086.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0087.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0088.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0089.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0090.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0091.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0092.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0093.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0094.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0095.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0096.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0097.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0098.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0099.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0100.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0101.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0102.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0103.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0104.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0105.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0106.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0107.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0108.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0109.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0110.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0111.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0112.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0113.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0114.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0115.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0116.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0117.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0118.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0119.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0120.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0121.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0122.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0123.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0124.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0125.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0126.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0127.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0128.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0129.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0130.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0131.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0132.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0133.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0134.png \n", + " inflating: kenney/Dot Matrix/Tiles/tile_0135.png \n", + " inflating: kenney/Dot Matrix/Tilesheet.txt \n", + " creating: kenney/Monochrome/\n", + " creating: kenney/Monochrome/Tilemap/\n", + " inflating: kenney/Monochrome/Tilemap/tilemap.png \n", + " inflating: kenney/Monochrome/Tilemap/tilemap_packed.png \n", + " creating: kenney/Monochrome/Tiles/\n", + " inflating: kenney/Monochrome/Tiles/tile_0000.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0001.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0002.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0003.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0004.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0005.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0006.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0007.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0008.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0009.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0010.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0011.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0012.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0013.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0014.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0015.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0016.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0017.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0018.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0019.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0020.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0021.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0022.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0023.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0024.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0025.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0026.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0027.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0028.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0029.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0030.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0031.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0032.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0033.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0034.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0035.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0036.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0037.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0038.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0039.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0040.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0041.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0042.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0043.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0044.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0045.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0046.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0047.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0048.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0049.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0050.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0051.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0052.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0053.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0054.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0055.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0056.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0057.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0058.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0059.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0060.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0061.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0062.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0063.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0064.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0065.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0066.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0067.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0068.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0069.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0070.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0071.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0072.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0073.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0074.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0075.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0076.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0077.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0078.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0079.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0080.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0081.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0082.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0083.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0084.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0085.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0086.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0087.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0088.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0089.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0090.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0091.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0092.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0093.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0094.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0095.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0096.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0097.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0098.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0099.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0100.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0101.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0102.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0103.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0104.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0105.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0106.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0107.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0108.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0109.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0110.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0111.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0112.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0113.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0114.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0115.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0116.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0117.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0118.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0119.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0120.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0121.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0122.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0123.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0124.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0125.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0126.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0127.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0128.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0129.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0130.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0131.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0132.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0133.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0134.png \n", + " inflating: kenney/Monochrome/Tiles/tile_0135.png \n", + " inflating: kenney/Monochrome/Tilesheet.txt \n", + " inflating: kenney/Instructions.url \n", + " inflating: kenney/License.txt \n", + " inflating: kenney/Preview.png \n", + " inflating: kenney/Sample.png \n", + " inflating: kenney/Visit Kenney.url \n", + " inflating: kenney/Visit Patreon.url \n", + " creating: kenney/Default/\n", + " creating: kenney/Default/Tilemap/\n", + " inflating: kenney/Default/Tilemap/tilemap.png \n", + " inflating: kenney/Default/Tilemap/tilemap_packed.png \n", + " creating: kenney/Default/Tiles/\n", + " inflating: kenney/Default/Tiles/tile_0000.png \n", + " inflating: kenney/Default/Tiles/tile_0001.png \n", + " inflating: kenney/Default/Tiles/tile_0002.png \n", + " inflating: kenney/Default/Tiles/tile_0003.png \n", + " inflating: kenney/Default/Tiles/tile_0004.png \n", + " inflating: kenney/Default/Tiles/tile_0005.png \n", + " inflating: kenney/Default/Tiles/tile_0006.png \n", + " inflating: kenney/Default/Tiles/tile_0007.png \n", + " inflating: kenney/Default/Tiles/tile_0008.png \n", + " inflating: kenney/Default/Tiles/tile_0009.png \n", + " inflating: kenney/Default/Tiles/tile_0010.png \n", + " inflating: kenney/Default/Tiles/tile_0011.png \n", + " inflating: kenney/Default/Tiles/tile_0012.png \n", + " inflating: kenney/Default/Tiles/tile_0013.png \n", + " inflating: kenney/Default/Tiles/tile_0014.png \n", + " inflating: kenney/Default/Tiles/tile_0015.png \n", + " inflating: kenney/Default/Tiles/tile_0016.png \n", + " inflating: kenney/Default/Tiles/tile_0017.png \n", + " inflating: kenney/Default/Tiles/tile_0018.png \n", + " inflating: kenney/Default/Tiles/tile_0019.png \n", + " inflating: kenney/Default/Tiles/tile_0020.png \n", + " inflating: kenney/Default/Tiles/tile_0021.png \n", + " inflating: kenney/Default/Tiles/tile_0022.png \n", + " inflating: kenney/Default/Tiles/tile_0023.png \n", + " inflating: kenney/Default/Tiles/tile_0024.png \n", + " inflating: kenney/Default/Tiles/tile_0025.png \n", + " inflating: kenney/Default/Tiles/tile_0026.png \n", + " inflating: kenney/Default/Tiles/tile_0027.png \n", + " inflating: kenney/Default/Tiles/tile_0028.png \n", + " inflating: kenney/Default/Tiles/tile_0029.png \n", + " inflating: kenney/Default/Tiles/tile_0030.png \n", + " inflating: kenney/Default/Tiles/tile_0031.png \n", + " inflating: kenney/Default/Tiles/tile_0032.png \n", + " inflating: kenney/Default/Tiles/tile_0033.png \n", + " inflating: kenney/Default/Tiles/tile_0034.png \n", + " inflating: kenney/Default/Tiles/tile_0035.png \n", + " inflating: kenney/Default/Tiles/tile_0036.png \n", + " inflating: kenney/Default/Tiles/tile_0037.png \n", + " inflating: kenney/Default/Tiles/tile_0038.png \n", + " inflating: kenney/Default/Tiles/tile_0039.png \n", + " inflating: kenney/Default/Tiles/tile_0040.png \n", + " inflating: kenney/Default/Tiles/tile_0041.png \n", + " inflating: kenney/Default/Tiles/tile_0042.png \n", + " inflating: kenney/Default/Tiles/tile_0043.png \n", + " inflating: kenney/Default/Tiles/tile_0044.png \n", + " inflating: kenney/Default/Tiles/tile_0045.png \n", + " inflating: kenney/Default/Tiles/tile_0046.png \n", + " inflating: kenney/Default/Tiles/tile_0047.png \n", + " inflating: kenney/Default/Tiles/tile_0048.png \n", + " inflating: kenney/Default/Tiles/tile_0049.png \n", + " inflating: kenney/Default/Tiles/tile_0050.png \n", + " inflating: kenney/Default/Tiles/tile_0051.png \n", + " inflating: kenney/Default/Tiles/tile_0052.png \n", + " inflating: kenney/Default/Tiles/tile_0053.png \n", + " inflating: kenney/Default/Tiles/tile_0054.png \n", + " inflating: kenney/Default/Tiles/tile_0055.png \n", + " inflating: kenney/Default/Tiles/tile_0056.png \n", + " inflating: kenney/Default/Tiles/tile_0057.png \n", + " inflating: kenney/Default/Tiles/tile_0058.png \n", + " inflating: kenney/Default/Tiles/tile_0059.png \n", + " inflating: kenney/Default/Tiles/tile_0060.png \n", + " inflating: kenney/Default/Tiles/tile_0061.png \n", + " inflating: kenney/Default/Tiles/tile_0062.png \n", + " inflating: kenney/Default/Tiles/tile_0063.png \n", + " inflating: kenney/Default/Tiles/tile_0064.png \n", + " inflating: kenney/Default/Tiles/tile_0065.png \n", + " inflating: kenney/Default/Tiles/tile_0066.png \n", + " inflating: kenney/Default/Tiles/tile_0067.png \n", + " inflating: kenney/Default/Tiles/tile_0068.png \n", + " inflating: kenney/Default/Tiles/tile_0069.png \n", + " inflating: kenney/Default/Tiles/tile_0070.png \n", + " inflating: kenney/Default/Tiles/tile_0071.png \n", + " inflating: kenney/Default/Tiles/tile_0072.png \n", + " inflating: kenney/Default/Tiles/tile_0073.png \n", + " inflating: kenney/Default/Tiles/tile_0074.png \n", + " inflating: kenney/Default/Tiles/tile_0075.png \n", + " inflating: kenney/Default/Tiles/tile_0076.png \n", + " inflating: kenney/Default/Tiles/tile_0077.png \n", + " inflating: kenney/Default/Tiles/tile_0078.png \n", + " inflating: kenney/Default/Tiles/tile_0079.png \n", + " inflating: kenney/Default/Tiles/tile_0080.png \n", + " inflating: kenney/Default/Tiles/tile_0081.png \n", + " inflating: kenney/Default/Tiles/tile_0082.png \n", + " inflating: kenney/Default/Tiles/tile_0083.png \n", + " inflating: kenney/Default/Tiles/tile_0084.png \n", + " inflating: kenney/Default/Tiles/tile_0085.png \n", + " inflating: kenney/Default/Tiles/tile_0086.png \n", + " inflating: kenney/Default/Tiles/tile_0087.png \n", + " inflating: kenney/Default/Tiles/tile_0088.png \n", + " inflating: kenney/Default/Tiles/tile_0089.png \n", + " inflating: kenney/Default/Tiles/tile_0090.png \n", + " inflating: kenney/Default/Tiles/tile_0091.png \n", + " inflating: kenney/Default/Tiles/tile_0092.png \n", + " inflating: kenney/Default/Tiles/tile_0093.png \n", + " inflating: kenney/Default/Tiles/tile_0094.png \n", + " inflating: kenney/Default/Tiles/tile_0095.png \n", + " inflating: kenney/Default/Tiles/tile_0096.png \n", + " inflating: kenney/Default/Tiles/tile_0097.png \n", + " inflating: kenney/Default/Tiles/tile_0098.png \n", + " inflating: kenney/Default/Tiles/tile_0099.png \n", + " inflating: kenney/Default/Tiles/tile_0100.png \n", + " inflating: kenney/Default/Tiles/tile_0101.png \n", + " inflating: kenney/Default/Tiles/tile_0102.png \n", + " inflating: kenney/Default/Tiles/tile_0103.png \n", + " inflating: kenney/Default/Tiles/tile_0104.png \n", + " inflating: kenney/Default/Tiles/tile_0105.png \n", + " inflating: kenney/Default/Tiles/tile_0106.png \n", + " inflating: kenney/Default/Tiles/tile_0107.png \n", + " inflating: kenney/Default/Tiles/tile_0108.png \n", + " inflating: kenney/Default/Tiles/tile_0109.png \n", + " inflating: kenney/Default/Tiles/tile_0110.png \n", + " inflating: kenney/Default/Tiles/tile_0111.png \n", + " inflating: kenney/Default/Tiles/tile_0112.png \n", + " inflating: kenney/Default/Tiles/tile_0113.png \n", + " inflating: kenney/Default/Tiles/tile_0114.png \n", + " inflating: kenney/Default/Tiles/tile_0115.png \n", + " inflating: kenney/Default/Tiles/tile_0116.png \n", + " inflating: kenney/Default/Tiles/tile_0117.png \n", + " inflating: kenney/Default/Tiles/tile_0118.png \n", + " inflating: kenney/Default/Tiles/tile_0119.png \n", + " inflating: kenney/Default/Tiles/tile_0120.png \n", + " inflating: kenney/Default/Tiles/tile_0121.png \n", + " inflating: kenney/Default/Tiles/tile_0122.png \n", + " inflating: kenney/Default/Tiles/tile_0123.png \n", + " inflating: kenney/Default/Tiles/tile_0124.png \n", + " inflating: kenney/Default/Tiles/tile_0125.png \n", + " inflating: kenney/Default/Tiles/tile_0126.png \n", + " inflating: kenney/Default/Tiles/tile_0127.png \n", + " inflating: kenney/Default/Tiles/tile_0128.png \n", + " inflating: kenney/Default/Tiles/tile_0129.png \n", + " inflating: kenney/Default/Tiles/tile_0130.png \n", + " inflating: kenney/Default/Tiles/tile_0131.png \n", + " inflating: kenney/Default/Tiles/tile_0132.png \n", + " inflating: kenney/Default/Tiles/tile_0133.png \n", + " inflating: kenney/Default/Tiles/tile_0134.png \n", + " inflating: kenney/Default/Tiles/tile_0135.png \n", + " inflating: kenney/Default/Tilesheet.txt \n" + ] + } + ], + "source": [ + "!unzip kenney_monochromerpg.zip -d kenney" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "dc9ed718-422b-4856-b2d2-33c6ad57a2c6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# We use PIL (python image library, actually now called Pillow) to open images" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "a7a29210-ee5a-41d5-baa6-54d54ea5f799", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from PIL import Image\n", + "from reportlab.pdfgen.canvas import Canvas\n", + "from reportlab.lib.pagesizes import letter, A4\n", + "from reportlab.lib.units import mm, cm\n", + "# from reportlab.pdfbase.ttfonts import TTFont, pdfmetrics\n", + "from pathlib import Path\n", + "\n", + "# size=A6\n", + "size = (75*mm, 75*mm)\n", + "\n", + "c = Canvas(\"tiles.pdf\", pagesize=size)\n", + "# Convert all the png files in the Kenney download (folder named Default from the zip above)\n", + "images = Path(\"kenney/Default/Tiles\")\n", + "for imagepath in images.glob(\"*.png\"):\n", + " image = Image.open(imagepath)\n", + " c.drawInlineImage(image, 0,0, width=75*mm,height=75*mm)\n", + " # show page saves the current page & starts a new one\n", + " c.showPage()\n", + "c.save()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a8633b0d-a43b-4225-9fc2-b3c4c54a86db", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "23cb5859-af12-4df6-9656-4aad0ecec81d", + "metadata": {}, + "source": [ + "## Webpage to PDF with weasyprint\n", + "\n", + "* https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#quickstart\n", + "* https://doc.courtbouillon.org/weasyprint/stable/first_steps.html?highlight=page%20size\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "49cd545c-acb7-4cad-8824-1bb9be50a420", + "metadata": {}, + "outputs": [], + "source": [ + "from weasyprint import HTML, CSS" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "b8cd94eb-eae9-4f7b-b847-2fbbbb141e9a", + "metadata": {}, + "outputs": [], + "source": [ + "url = \"https://www.ruetir.com/2022/03/09/bold-statement-loot-boxes-in-football-game-fifa-now-allowed/\"\n", + "css = CSS(string='@page { size: 75mm 75mm; margin: 0mm }')\n", + "HTML(url).write_pdf('bold-statement-loot-boxes.pdf', stylesheets=[css])" + ] + }, + { + "cell_type": "markdown", + "id": "3c7627fb-1e55-49a5-a2f6-be97e888b740", + "metadata": {}, + "source": [ + "so like the first part ... D=titles.pdf etc just names the PDF, when you then say D2 after the command **cat** it takes adds page 2 of titles.pdf to the eventual *output* (so **cat** starts the command and **output** then ends it + the name of the file to save, it's a little weird syntax, but super useful!!!!" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "c5efc479-8109-46b0-bbe1-7214de6c055c", + "metadata": {}, + "outputs": [], + "source": [ + "!pdftk A=grid.pdf B=bold-statement-loot-boxes.pdf C=tiles.pdf D=titles.pdf cat D1 A D2 B D3 C output all.pdf" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "cb2cbf7b-9e03-48de-b7c0-f6a089f8e850", + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "PDFTK(1)\t\t General Commands Manual\t\t PDFTK(1)\n", + "\n", + "NAME\n", + " pdftk - A handy tool for manipulating PDF\n", + "\n", + "SYNOPSIS\n", + " pdftk \n", + "\t [ input_pw ]\n", + "\t [ ]\n", + "\t [ output ]\n", + "\t [ encrypt_40bit | encrypt_128bit ]\n", + "\t [ allow ]\n", + "\t [ owner_pw ]\n", + "\t [ user_pw ]\n", + "\t [ flatten ] [ need_appearances ]\n", + "\t [ compress | uncompress ]\n", + "\t [ keep_first_id | keep_final_id ] [ drop_xfa ] [ drop_xmp ]\n", + "\t [ verbose ] [ dont_ask | do_ask ]\n", + " Where:\n", + "\t may be empty, or:\n", + "\t [ cat | shuffle | burst | rotate |\n", + "\t generate_fdf | fill_form |\n", + "\t background | multibackground |\n", + "\t stamp | multistamp |\n", + "\t dump_data | dump_data_utf8 |\n", + "\t dump_data_fields | dump_data_fields_utf8 |\n", + "\t dump_data_annots |\n", + "\t update_info | update_info_utf8 |\n", + "\t attach_files | unpack_files ]\n", + "\n", + " For Complete Help: pdftk --help\n", + "\n", + "DESCRIPTION\n", + " If PDF is electronic paper, then pdftk is an electronic staple-remover,\n", + " hole-punch, binder, secret-decoder-ring, and X-Ray-glasses. Pdftk is a\n", + " simple tool for doing everyday things with PDF documents. Use it to:\n", + "\n", + " * Merge PDF Documents or Collate PDF Page Scans\n", + " * Split PDF Pages into a New Document\n", + " * Rotate PDF Documents or Pages\n", + " * Decrypt Input as Necessary (Password Required)\n", + " * Encrypt Output as Desired\n", + " * Fill PDF Forms with X/FDF Data and/or Flatten Forms\n", + " * Generate FDF Data Stencils from PDF Forms\n", + " * Apply a Background Watermark or a Foreground Stamp\n", + " * Report PDF Metrics, Bookmarks and Metadata\n", + " * Add/Update PDF Bookmarks or Metadata\n", + " * Attach Files to PDF Pages or the PDF Document\n", + " * Unpack PDF Attachments\n", + " * Burst a PDF Document into Single Pages\n", + " * Uncompress and Re-Compress Page Streams\n", + " * Repair Corrupted PDF (Where Possible)\n", + "\n", + "OPTIONS\n", + " A summary of options is included below.\n", + "\n", + " --help, -h\n", + "\t Show this summary of options.\n", + "\n", + " \n", + "\t A list of the input PDF files. If you plan to combine these PDFs\n", + "\t (without using handles) then list files in the order you want\n", + "\t them combined. Use - to pass a single PDF into pdftk via stdin.\n", + "\t Input files can be associated with handles, where a handle is\n", + "\t one or more upper-case letters:\n", + "\n", + "\t =\n", + "\n", + "\t Handles are often omitted. They are useful when specifying PDF\n", + "\t passwords or page ranges, later.\n", + "\n", + "\t For example: A=input1.pdf QT=input2.pdf M=input3.pdf\n", + "\n", + " [input_pw ]\n", + "\t Input PDF owner passwords, if necessary, are associated with\n", + "\t files by using their handles:\n", + "\n", + "\t =\n", + "\n", + "\t If handles are not given, then passwords are associated with in‐\n", + "\t put files by order.\n", + "\n", + "\t Most pdftk features require that encrypted input PDF are accom‐\n", + "\t panied by the ~owner~ password. If the input PDF has no owner\n", + "\t password, then the user password must be given, instead.\tIf the\n", + "\t input PDF has no passwords, then no password should be given.\n", + "\n", + "\t When running in do_ask mode, pdftk will prompt you for a pass‐\n", + "\t word if the supplied password is incorrect or none was given.\n", + "\n", + " [ ]\n", + "\t Available operations are: cat, shuffle, burst, rotate, gener‐\n", + "\t ate_fdf, fill_form, background, multibackground, stamp, multi‐\n", + "\t stamp, dump_data, dump_data_utf8, dump_data_fields,\n", + "\t dump_data_fields_utf8, dump_data_annots, update_info, up‐\n", + "\t date_info_utf8, attach_files, unpack_files. Some operations\n", + "\t takes additional arguments, described below.\n", + "\n", + "\t If this optional argument is omitted, then pdftk runs in 'fil‐\n", + "\t ter' mode. Filter mode takes only one PDF input and creates a\n", + "\t new PDF after applying all of the output options, like encryp‐\n", + "\t tion and compression.\n", + "\n", + "\t cat []\n", + "\t\t Assembles (catenates) pages from input PDFs to create a new\n", + "\t\t PDF. Use cat to merge PDF pages or to split PDF pages from\n", + "\t\t documents. You can also use it to rotate PDF pages. Page or‐\n", + "\t\t der in the new PDF is specified by the order of the given\n", + "\t\t page ranges. Page ranges are described like this:\n", + "\n", + "\t\t [[-[]]][]\n", + "\n", + "\t\t Where the handle identifies one of the input PDF files, and\n", + "\t\t the beginning and ending page numbers are one-based refer‐\n", + "\t\t ences to pages in the PDF file. The qualifier can be even or\n", + "\t\t odd, and the page rotation can be north, south, east, west,\n", + "\t\t left, right, or down.\n", + "\n", + "\t\t If a PDF handle is given but no pages are specified, then the\n", + "\t\t entire PDF is used. If no pages are specified for any of the\n", + "\t\t input PDFs, then the input PDFs' bookmarks are also merged\n", + "\t\t and included in the output.\n", + "\n", + "\t\t If the handle is omitted from the page range, then the pages\n", + "\t\t are taken from the first input PDF.\n", + "\n", + "\t\t The even qualifier causes pdftk to use only the even-numbered\n", + "\t\t PDF pages, so 1-6even yields pages 2, 4 and 6 in that order.\n", + "\t\t 6-1even yields pages 6, 4 and 2 in that order.\n", + "\n", + "\t\t The odd qualifier works similarly to the even.\n", + "\n", + "\t\t The page rotation setting can cause pdftk to rotate pages and\n", + "\t\t documents. Each option sets the page rotation as follows (in\n", + "\t\t degrees): north: 0, east: 90, south: 180, west: 270, left:\n", + "\t\t -90, right: +90, down: +180. left, right, and down make rela‐\n", + "\t\t tive adjustments to a page's rotation.\n", + "\n", + "\t\t If no arguments are passed to cat, then pdftk combines all\n", + "\t\t input PDFs in the order they were given to create the output.\n", + "\n", + "\t\t NOTES:\n", + "\t\t * may be less than .\n", + "\t\t * The keyword end may be used to reference the final page of\n", + "\t\t a document instead of a page number.\n", + "\t\t * Reference a single page by omitting the ending page number.\n", + "\t\t * The handle may be used alone to represent the entire PDF\n", + "\t\t document, e.g., B1-end is the same as B.\n", + "\t\t * You can reference page numbers in reverse order by prefix‐\n", + "\t\t ing them with the letter r. For example, page r1 is the last\n", + "\t\t page of the document, r2 is the next-to-last page of the doc‐\n", + "\t\t ument, and rend is the first page of the document. You can\n", + "\t\t use this prefix in ranges, too, for example r3-r1 is the last\n", + "\t\t three pages of a PDF.\n", + "\n", + "\t\t Page Range Examples without Handles:\n", + "\t\t 1-endeast - rotate entire document 90 degrees\n", + "\t\t 5 11 20 - take single pages from input PDF\n", + "\t\t 5-25oddwest - take odd pages in range, rotate 90 degrees\n", + "\t\t 6-1 - reverse pages in range from input PDF\n", + "\n", + "\t\t Page Range Examples Using Handles:\n", + "\t\t Say A=in1.pdf B=in2.pdf, then:\n", + "\t\t A1-21 - take range from in1.pdf\n", + "\t\t Bend-1odd - take all odd pages from in2.pdf in reverse order\n", + "\t\t A72 - take a single page from in1.pdf\n", + "\t\t A1-21 Beven A72 - assemble pages from both in1.pdf and\n", + "\t\t in2.pdf\n", + "\t\t Awest - rotate entire in1.pdf document 90 degrees\n", + "\t\t B - use all of in2.pdf\n", + "\t\t A2-30evenleft - take the even pages from the range, remove 90\n", + "\t\t degrees from each page's rotation\n", + "\t\t A A - catenate in1.pdf with in1.pdf\n", + "\t\t Aevenwest Aoddeast - apply rotations to even pages, odd pages\n", + "\t\t from in1.pdf\n", + "\t\t Awest Bwest Bdown - catenate rotated documents\n", + "\n", + "\t shuffle []\n", + "\t\t Collates pages from input PDFs to create a new PDF. Works\n", + "\t\t like the cat operation except that it takes one page at a\n", + "\t\t time from each page range to assemble the output PDF.\tIf one\n", + "\t\t range runs out of pages, it continues with the remaining\n", + "\t\t ranges. Ranges can use all of the features described above\n", + "\t\t for cat, like reverse page ranges, multiple ranges from a\n", + "\t\t single PDF, and page rotation.\t This feature was designed to\n", + "\t\t help collate PDF pages after scanning paper documents.\n", + "\n", + "\t burst\t Splits a single input PDF document into individual pages.\n", + "\t\t Also creates a report named doc_data.txt which is the same as\n", + "\t\t the output from dump_data. If the output section is omitted,\n", + "\t\t then PDF pages are named: pg_%04d.pdf, e.g.: pg_0001.pdf,\n", + "\t\t pg_0002.pdf, etc. To name these pages yourself, supply a\n", + "\t\t printf-styled format string via the output section. For ex‐\n", + "\t\t ample, if you want pages named: page_01.pdf, page_02.pdf,\n", + "\t\t etc., pass output page_%02d.pdf to pdftk. Encryption can be\n", + "\t\t applied to the output by appending output options such as\n", + "\t\t owner_pw, e.g.:\n", + "\n", + "\t\t pdftk in.pdf burst owner_pw foopass\n", + "\n", + "\t rotate []\n", + "\t\t Takes a single input PDF and rotates just the specified\n", + "\t\t pages.\t All other pages remain unchanged. The page order re‐\n", + "\t\t mains unchaged. Specify the pages to rotate using the same\n", + "\t\t notation as you would with cat, except you omit the pages\n", + "\t\t that you aren't rotating:\n", + "\n", + "\t\t [[-[]]][]\n", + "\n", + "\t\t The qualifier can be even or odd, and the page rotation can\n", + "\t\t be north, south, east, west, left, right, or down.\n", + "\n", + "\t\t Each option sets the page rotation as follows (in degrees):\n", + "\t\t north: 0, east: 90, south: 180, west: 270, left: -90, right:\n", + "\t\t +90, down: +180. left, right, and down make relative adjust‐\n", + "\t\t ments to a page's rotation.\n", + "\n", + "\t\t The given order of the pages doesn't change the page order in\n", + "\t\t the output.\n", + "\n", + "\t generate_fdf\n", + "\t\t Reads a single input PDF file and generates an FDF file suit‐\n", + "\t\t able for fill_form out of it to the given output filename or\n", + "\t\t (if no output is given) to stdout. Does not create a new\n", + "\t\t PDF.\n", + "\n", + "\t fill_form \n", + "\t\t Fills the single input PDF's form fields with the data from\n", + "\t\t an FDF file, XFDF file or stdin. Enter the data filename af‐\n", + "\t\t ter fill_form, or use - to pass the data via stdin, like so:\n", + "\n", + "\t\t pdftk form.pdf fill_form data.fdf output form.filled.pdf\n", + "\n", + "\t\t If the input FDF file includes Rich Text formatted data in\n", + "\t\t addition to plain text, then the Rich Text data is packed\n", + "\t\t into the form fields as well as the plain text. Pdftk also\n", + "\t\t sets a flag that cues Reader/Acrobat to generate new field\n", + "\t\t appearances based on the Rich Text data. So when the user\n", + "\t\t opens the PDF, the viewer will create the Rich Text appear‐\n", + "\t\t ance on the spot. If the user's PDF viewer does not support\n", + "\t\t Rich Text, then the user will see the plain text data in‐\n", + "\t\t stead.\t If you flatten this form before Acrobat has a chance\n", + "\t\t to create (and save) new field appearances, then the plain\n", + "\t\t text field data is what you'll see.\n", + "\n", + "\t\t Also see the flatten and need_appearances options.\n", + "\n", + "\t background \n", + "\t\t Applies a PDF watermark to the background of a single input\n", + "\t\t PDF. Pass the background PDF's filename after background\n", + "\t\t like so:\n", + "\n", + "\t\t pdftk in.pdf background back.pdf output out.pdf\n", + "\n", + "\t\t Pdftk uses only the first page from the background PDF and\n", + "\t\t applies it to every page of the input PDF. This page is\n", + "\t\t scaled and rotated as needed to fit the input page. You can\n", + "\t\t use - to pass a background PDF into pdftk via stdin.\n", + "\n", + "\t\t If the input PDF does not have a transparent background (such\n", + "\t\t as a PDF created from page scans) then the resulting back‐\n", + "\t\t ground won't be visible -- use the stamp operation instead.\n", + "\n", + "\t multibackground \n", + "\t\t Same as the background operation, but applies each page of\n", + "\t\t the background PDF to the corresponding page of the input\n", + "\t\t PDF. If the input PDF has more pages than the stamp PDF,\n", + "\t\t then the final stamp page is repeated across these remaining\n", + "\t\t pages in the input PDF.\n", + "\n", + "\t stamp \n", + "\t\t This behaves just like the background operation except it\n", + "\t\t overlays the stamp PDF page on top of the input PDF docu‐\n", + "\t\t ment's pages.\tThis works best if the stamp PDF page has a\n", + "\t\t transparent background.\n", + "\n", + "\t multistamp \n", + "\t\t Same as the stamp operation, but applies each page of the\n", + "\t\t background PDF to the corresponding page of the input PDF.\n", + "\t\t If the input PDF has more pages than the stamp PDF, then the\n", + "\t\t final stamp page is repeated across these remaining pages in\n", + "\t\t the input PDF.\n", + "\n", + "\t dump_data\n", + "\t\t Reads a single input PDF file and reports its metadata, book‐\n", + "\t\t marks (a/k/a outlines), page metrics (media, rotation and la‐\n", + "\t\t bels), data embedded by STAMPtk (see STAMPtk's embed option)\n", + "\t\t and other data to the given output filename or (if no output\n", + "\t\t is given) to stdout. Non-ASCII characters are encoded as XML\n", + "\t\t numerical entities. Does not create a new PDF.\n", + "\n", + "\t dump_data_utf8\n", + "\t\t Same as dump_data excepct that the output is encoded as\n", + "\t\t UTF-8.\n", + "\n", + "\t dump_data_fields\n", + "\t\t Reads a single input PDF file and reports form field statis‐\n", + "\t\t tics to the given output filename or (if no output is given)\n", + "\t\t to stdout. Non-ASCII characters are encoded as XML numerical\n", + "\t\t entities. Does not create a new PDF.\n", + "\n", + "\t dump_data_fields_utf8\n", + "\t\t Same as dump_data_fields excepct that the output is encoded\n", + "\t\t as UTF-8.\n", + "\n", + "\t dump_data_annots\n", + "\t\t This operation currently reports only link annotations.\n", + "\t\t Reads a single input PDF file and reports annotation informa‐\n", + "\t\t tion to the given output filename or (if no output is given)\n", + "\t\t to stdout. Non-ASCII characters are encoded as XML numerical\n", + "\t\t entities. Does not create a new PDF.\n", + "\n", + "\t update_info \n", + "\t\t Changes the bookmarks and metadata in a single PDF's Info\n", + "\t\t dictionary to match the input data file. The input data file\n", + "\t\t uses the same syntax as the output from dump_data. Non-ASCII\n", + "\t\t characters should be encoded as XML numerical entities.\n", + "\n", + "\t\t This operation does not change the metadata stored in the\n", + "\t\t PDF's XMP stream, if it has one. (For this reason you should\n", + "\t\t include a ModDate entry in your updated info with a current\n", + "\t\t date/timestamp, format: D:YYYYMMDDHHmmSS, e.g. D:201307241346\n", + "\t\t -- omitted data after YYYY revert to default values.)\n", + "\n", + "\t\t For example:\n", + "\n", + "\t\t pdftk in.pdf update_info in.info output out.pdf\n", + "\n", + "\t update_info_utf8 \n", + "\t\t Same as update_info except that the input is encoded as\n", + "\t\t UTF-8.\n", + "\n", + "\t attach_files [to_page ]\n", + "\t\t Packs arbitrary files into a PDF using PDF's file attachment\n", + "\t\t features. More than one attachment may be listed after at‐\n", + "\t\t tach_files. Attachments are added at the document level un‐\n", + "\t\t less the optional to_page option is given, in which case the\n", + "\t\t files are attached to the given page number (the first page\n", + "\t\t is 1, the final page is end). For example:\n", + "\n", + "\t\t pdftk in.pdf attach_files table1.html table2.html to_page 6\n", + "\t\t output out.pdf\n", + "\n", + "\t unpack_files\n", + "\t\t Copies all of the attachments from the input PDF into the\n", + "\t\t current folder or to an output directory given after output.\n", + "\t\t For example:\n", + "\n", + "\t\t pdftk report.pdf unpack_files output ~/atts/\n", + "\n", + "\t\t or, interactively:\n", + "\n", + "\t\t pdftk report.pdf unpack_files output PROMPT\n", + "\n", + " [output ]\n", + "\t The output PDF filename may not be set to the name of an input\n", + "\t filename. Use - to output to stdout. When using the dump_data\n", + "\t operation, use output to set the name of the output data file.\n", + "\t When using the unpack_files operation, use output to set the\n", + "\t name of an output directory. When using the burst operation,\n", + "\t you can use output to control the resulting PDF page filenames\n", + "\t (described above).\n", + "\n", + " [encrypt_40bit | encrypt_128bit]\n", + "\t If an output PDF user or owner password is given, output PDF en‐\n", + "\t cryption strength defaults to 128 bits. This can be overridden\n", + "\t by specifying encrypt_40bit.\n", + "\n", + " [allow ]\n", + "\t Permissions are applied to the output PDF only if an encryption\n", + "\t strength is specified or an owner or user password is given. If\n", + "\t permissions are not specified, they default to 'none,' which\n", + "\t means all of the following features are disabled.\n", + "\n", + "\t The permissions section may include one or more of the following\n", + "\t features:\n", + "\n", + "\t Printing\n", + "\t\t Top Quality Printing\n", + "\n", + "\t DegradedPrinting\n", + "\t\t Lower Quality Printing\n", + "\n", + "\t ModifyContents\n", + "\t\t Also allows Assembly\n", + "\n", + "\t Assembly\n", + "\n", + "\t CopyContents\n", + "\t\t Also allows ScreenReaders\n", + "\n", + "\t ScreenReaders\n", + "\n", + "\t ModifyAnnotations\n", + "\t\t Also allows FillIn\n", + "\n", + "\t FillIn\n", + "\n", + "\t AllFeatures\n", + "\t\t Allows the user to perform all of the above, and top\n", + "\t\t quality printing.\n", + "\n", + " [owner_pw ]\n", + "\n", + " [user_pw ]\n", + "\t If an encryption strength is given but no passwords are sup‐\n", + "\t plied, then the owner and user passwords remain empty, which\n", + "\t means that the resulting PDF may be opened and its security pa‐\n", + "\t rameters altered by anybody.\n", + "\n", + " [compress | uncompress]\n", + "\t These are only useful when you want to edit PDF code in a text\n", + "\t editor like vim or emacs.\t Remove PDF page stream compression by\n", + "\t applying the uncompress filter. Use the compress filter to re‐\n", + "\t store compression.\n", + "\n", + " [flatten]\n", + "\t Use this option to merge an input PDF's interactive form fields\n", + "\t (and their data) with the PDF's pages. Only one input PDF may be\n", + "\t given. Sometimes used with the fill_form operation.\n", + "\n", + " [need_appearances]\n", + "\t Sets a flag that cues Reader/Acrobat to generate new field ap‐\n", + "\t pearances based on the form field values.\t Use this when filling\n", + "\t a form with non-ASCII text to ensure the best presentation in\n", + "\t Adobe Reader or Acrobat.\tIt won't work when combined with the\n", + "\t flatten option.\n", + "\n", + " [keep_first_id | keep_final_id]\n", + "\t When combining pages from multiple PDFs, use one of these op‐\n", + "\t tions to copy the document ID from either the first or final in‐\n", + "\t put document into the new output PDF. Otherwise pdftk creates a\n", + "\t new document ID for the output PDF. When no operation is given,\n", + "\t pdftk always uses the ID from the (single) input PDF.\n", + "\n", + " [drop_xfa]\n", + "\t If your input PDF is a form created using Acrobat 7 or Adobe De‐\n", + "\t signer, then it probably has XFA data. Filling such a form us‐\n", + "\t ing pdftk yields a PDF with data that fails to display in Acro‐\n", + "\t bat 7 (and 6?). The workaround solution is to remove the form's\n", + "\t XFA data, either before you fill the form using pdftk or at the\n", + "\t time you fill the form. Using this option causes pdftk to omit\n", + "\t the XFA data from the output PDF form.\n", + "\n", + "\t This option is only useful when running pdftk on a single input\n", + "\t PDF. When assembling a PDF from multiple inputs using pdftk,\n", + "\t any XFA data in the input is automatically omitted.\n", + "\n", + " [drop_xmp]\n", + "\t Many PDFs store document metadata using both an Info dictionary\n", + "\t (old school) and an XMP stream (new school). Pdftk's up‐\n", + "\t date_info operation can update the Info dictionary, but not the\n", + "\t XMP stream. The proper remedy for this is to include a ModDate\n", + "\t entry in your updated info with a current date/timestamp. The\n", + "\t date/timestamp format is: D:YYYYMMDDHHmmSS, e.g. D:201307241346\n", + "\t -- omitted data after YYYY revert to default values. This newer\n", + "\t ModDate should cue PDF viewers that the Info metadata is more\n", + "\t current than the XMP data.\n", + "\n", + "\t Alternatively, you might prefer to remove the XMP stream from\n", + "\t the PDF altogether -- that's what this option does. Note that\n", + "\t objects inside the PDF might have their own, separate XMP meta‐\n", + "\t data streams, and that drop_xmp does not remove those. It only\n", + "\t removes the PDF's document-level XMP stream.\n", + "\n", + " [verbose]\n", + "\t By default, pdftk runs quietly. Append verbose to the end and it\n", + "\t will speak up.\n", + "\n", + " [dont_ask | do_ask]\n", + "\t Depending on the compile-time settings (see ASK_ABOUT_WARNINGS),\n", + "\t pdftk might prompt you for further input when it encounters a\n", + "\t problem, such as a bad password. Override this default behavior\n", + "\t by adding dont_ask (so pdftk won't ask you what to do) or do_ask\n", + "\t (so pdftk will ask you what to do).\n", + "\n", + "\t When running in dont_ask mode, pdftk will over-write files with\n", + "\t its output without notice.\n", + "\n", + "EXAMPLES\n", + " Collate scanned pages\n", + "\t pdftk A=even.pdf B=odd.pdf shuffle A B output collated.pdf\n", + "\t or if odd.pdf is in reverse order:\n", + "\t pdftk A=even.pdf B=odd.pdf shuffle A Bend-1 output collated.pdf\n", + "\n", + " Decrypt a PDF\n", + "\t pdftk secured.pdf input_pw foopass output unsecured.pdf\n", + "\n", + " Encrypt a PDF using 128-bit strength (the default), withhold all per‐\n", + " missions (the default)\n", + "\t pdftk 1.pdf output 1.128.pdf owner_pw foopass\n", + "\n", + " Same as above, except password 'baz' must also be used to open output\n", + " PDF\n", + "\t pdftk 1.pdf output 1.128.pdf owner_pw foo user_pw baz\n", + "\n", + " Same as above, except printing is allowed (once the PDF is open)\n", + "\t pdftk 1.pdf output 1.128.pdf owner_pw foo user_pw baz allow printing\n", + "\n", + " Join in1.pdf and in2.pdf into a new PDF, out1.pdf\n", + "\t pdftk in1.pdf in2.pdf cat output out1.pdf\n", + "\t or (using handles):\n", + "\t pdftk A=in1.pdf B=in2.pdf cat A B output out1.pdf\n", + "\t or (using wildcards):\n", + "\t pdftk *.pdf cat output combined.pdf\n", + "\n", + " Remove page 13 from in1.pdf to create out1.pdf\n", + "\t pdftk in.pdf cat 1-12 14-end output out1.pdf\n", + "\t or:\n", + "\t pdftk A=in1.pdf cat A1-12 A14-end output out1.pdf\n", + "\n", + " Apply 40-bit encryption to output, revoking all permissions (the de‐\n", + " fault). Set the owner PW to 'foopass'.\n", + "\t pdftk 1.pdf 2.pdf cat output 3.pdf encrypt_40bit owner_pw foopass\n", + "\n", + " Join two files, one of which requires the password 'foopass'. The out‐\n", + " put is not encrypted.\n", + "\t pdftk A=secured.pdf 2.pdf input_pw A=foopass cat output 3.pdf\n", + "\n", + " Uncompress PDF page streams for editing the PDF in a text editor (e.g.,\n", + " vim, emacs)\n", + "\t pdftk doc.pdf output doc.unc.pdf uncompress\n", + "\n", + " Repair a PDF's corrupted XREF table and stream lengths, if possible\n", + "\t pdftk broken.pdf output fixed.pdf\n", + "\n", + " Burst a single PDF document into pages and dump its data to\n", + " doc_data.txt\n", + "\t pdftk in.pdf burst\n", + "\n", + " Burst a single PDF document into encrypted pages. Allow low-quality\n", + " printing\n", + "\t pdftk in.pdf burst owner_pw foopass allow DegradedPrinting\n", + "\n", + " Write a report on PDF document metadata and bookmarks to report.txt\n", + "\t pdftk in.pdf dump_data output report.txt\n", + "\n", + " Rotate the first PDF page to 90 degrees clockwise\n", + "\t pdftk in.pdf cat 1east 2-end output out.pdf\n", + "\n", + " Rotate an entire PDF document to 180 degrees\n", + "\t pdftk in.pdf cat 1-endsouth output out.pdf\n", + "\n", + "NOTES\n", + " This is a port of pdftk to java. See\n", + " https://gitlab.com/marcvinyals/pdftk\n", + " The original program can be found at www.pdftk.com\n", + "\n", + "AUTHOR\n", + " Original author of pdftk is Sid Steward (sid.steward at pdflabs dot\n", + " com).\n", + "\n", + "\t\t\t\t May 11, 2018\t\t\t PDFTK(1)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "man pdftk" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b688e8f9-c1be-4982-8323-6fe7cfe10498", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}