From 8f358334d7a566bd5f10e07feb97f8bd0e4b71e0 Mon Sep 17 00:00:00 2001 From: Michael Murtaugh Date: Thu, 10 Mar 2022 14:03:01 +0100 Subject: [PATCH] notebook + font --- OSP-DIN.ttf | Bin 0 -> 27232 bytes PythonPDFPostits.ipynb | 1489 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1489 insertions(+) create mode 100644 OSP-DIN.ttf create mode 100644 PythonPDFPostits.ipynb diff --git a/OSP-DIN.ttf b/OSP-DIN.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d30ca557d1e20abb8c96ecc986152844cac94e90 GIT binary patch literal 27232 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 CN-b3Y literal 0 HcmV?d00001 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 +}