From a47c04dfc54bef96c97b3eab757a25764f7be373 Mon Sep 17 00:00:00 2001 From: manetta Date: Tue, 6 Oct 2020 16:04:42 +0200 Subject: [PATCH] updating the ASCII and reportlab canvas notebooks + reportlab cheatsheet, clearing all outputs --- ASCII-canvas-to-PDF.ipynb | 113 ++------ reportlab-canvas-A4-bag-of-words.ipynb | 345 +++++++++++++------------ reportlab-cheatsheet.ipynb | 255 ++++-------------- 3 files changed, 244 insertions(+), 469 deletions(-) diff --git a/ASCII-canvas-to-PDF.ipynb b/ASCII-canvas-to-PDF.ipynb index 53eae10..f8f32b0 100644 --- a/ASCII-canvas-to-PDF.ipynb +++ b/ASCII-canvas-to-PDF.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -35,81 +35,11 @@ }, { "cell_type": "code", - "execution_count": 88, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - ] - } - ], + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], "source": [ "# Simple fill-up of a page, to set the reach of our canvas\n", "lines = [] # All the lines will be stored here\n", @@ -129,7 +59,7 @@ }, "outputs": [], "source": [ - "# Another variation\n", + "# Another way to fill-up the page\n", "import random \n", "\n", "lines = []\n", @@ -149,14 +79,17 @@ }, { "cell_type": "code", - "execution_count": 90, - "metadata": {}, + "execution_count": null, + "metadata": { + "scrolled": true + }, "outputs": [], "source": [ - "# Same variation, but with multiple pages\n", + "# Same as above + a \"switch\" to make multipaged PDFs\n", "import random \n", "\n", "multipage = True\n", + "number_of_pages = 100\n", "\n", "lines = []\n", "pages = []\n", @@ -164,7 +97,7 @@ "txt = open('txt/language.txt', 'r').read()\n", "words = txt.split()\n", "\n", - "for page in range(100):\n", + "for page in range(number_of_pages):\n", " \n", " for linenumber in range(height):\n", " word = random.choice(words)\n", @@ -176,7 +109,10 @@ " # Add a page\n", " pages.append(lines)\n", " lines = []\n", - " " + "\n", + "for page in pages:\n", + " print('\\n'.join(page))\n", + " print('-' * width)" ] }, { @@ -209,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -220,7 +156,7 @@ "pagewidth = 210*mm\n", "pageheight = 297*mm\n", "\n", - "c = Canvas(\"pdf/ASCII-canvas-to-PDF.pdf\", pagesize=(pagewidth, pageheight), bottomup=0)\n", + "c = Canvas(\"ASCII-canvas-to-PDF.pdf\", pagesize=(pagewidth, pageheight), bottomup=0)\n", "c.setFont('Courier', 12)\n", "\n", "start_y = 10*mm # start position of the lines\n", @@ -242,13 +178,6 @@ " \n", "c.save()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/reportlab-canvas-A4-bag-of-words.ipynb b/reportlab-canvas-A4-bag-of-words.ipynb index fabee4a..286e8fa 100644 --- a/reportlab-canvas-A4-bag-of-words.ipynb +++ b/reportlab-canvas-A4-bag-of-words.ipynb @@ -1,29 +1,45 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Reportlab Canvas (A4) - Bag of Words" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An example notebook to make PDFs with Reportlab. \n", + "\n", + "This notebook draws 100 words on an A4 PDF." + ] + }, { "cell_type": "code", - "execution_count": 266, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from reportlab.pdfgen.canvas import Canvas\n", "from reportlab.lib.pagesizes import A4\n", "from reportlab.lib.units import mm\n", - "from reportlab.lib.colors import pink, magenta, red, blue, yellow, lightyellow" + "from reportlab.lib.colors import magenta, lightgrey" ] }, { "cell_type": "code", - "execution_count": 277, + "execution_count": 40, "metadata": {}, "outputs": [], "source": [ - "c = Canvas(\"pdf/reportlab-canvas-A4-bag-of-words.pdf\", pagesize=(210*mm, 297*mm), bottomup=0)" + "c = Canvas(\"reportlab-canvas-A4-bag-of-words.pdf\", pagesize=(210*mm, 297*mm), bottomup=0)" ] }, { "cell_type": "code", - "execution_count": 268, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ @@ -32,31 +48,18 @@ }, { "cell_type": "code", - "execution_count": 269, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "# Draw a background color\n", - "c.setFillColor(lightyellow)\n", + "c.setFillColor(lightgrey)\n", "c.rect(0, 0, A4[0], A4[1], stroke=0, fill=1)" ] }, { "cell_type": "code", - "execution_count": 270, - "metadata": {}, - "outputs": [], - "source": [ - "# Draw a bag-of-words on the canvas, on random positions\n", - "import random\n", - "\n", - "txt = open('txt/language.txt', 'r').read()\n", - "words = txt.split()" - ] - }, - { - "cell_type": "code", - "execution_count": 271, + "execution_count": 43, "metadata": {}, "outputs": [], "source": [ @@ -73,124 +76,166 @@ }, { "cell_type": "code", - "execution_count": 275, - "metadata": {}, + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# First bag-of-words: 100 randomly picked and positioned words, based on the text *Language and Software Studies* (`txt/language.txt`).\n", + "# Use the random module and open the language.txt file \n", + "import random\n", + "\n", + "txt = open('txt/language.txt', 'r').read()\n", + "words = txt.split()\n", + "\n", + "# Draw a random bag-of-words on the canvas\n", + "for n in range(100):\n", + " x = random.randint(0, 190)\n", + " y = random.randint(0, 280)\n", + " word = random.choice(words).strip(',.')\n", + " print(x, y, word)\n", + " c.drawString(x*mm, y*mm, word)\n", + "\n", + "# Add a small caption\n", + "c.setFont('Courier', 10)\n", + "c.setFillColor(blue)\n", + "c.drawCentredString(105*mm, 290*mm, 'Random words from Language and Software Studies, by Florian Cramer (2005)')\n", + "\n", + "# Save the PDF!\n", + "c.save()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "scrolled": true + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "37 107 a\n", - "24 100 formal\n", - "126 264 a\n", - "58 279 controls\n", - "41 250 an\n", - "36 142 program\n", - "111 153 programming\n", - "32 228 be\n", - "71 166 Originally\n", - "154 267 operations)\n", - "97 60 are\n", - "187 158 the\n", - "98 205 an\n", - "169 229 “code”\n", - "175 144 analog\n", - "166 9 yet\n", - "82 182 the\n", - "136 34 a\n", - "35 268 7\n", - "13 21 of\n", - "152 254 of\n", - "81 157 call\n", - "160 104 tomorrow\n", - "141 47 promises\n", - "140 220 of\n", - "155 201 The\n", - "62 59 terms.”\n", - "41 246 difficult\n", - "61 139 of\n", - "154 279 in\n", - "48 279 coded\n", - "59 88 artists\n", - "146 186 eventual\n", - "90 26 virus\n", - "102 261 act\n", - "55 265 computer\n", - "83 40 reflect\n", - "126 144 experiments\n", - "99 30 computation\n", - "5 221 concrete\n", - "96 129 occurs\n", - "19 89 computes\n", - "181 34 their\n", - "9 57 is\n", - "157 68 “performative”\n", - "19 95 computer\n", - "30 44 in\n", - "88 114 instructions\n", - "65 188 computer\n", - "81 149 German\n", - "70 207 whatever\n", - "113 31 representation\n", - "166 82 and\n", - "15 55 to\n", - "57 163 and\n", - "118 196 is\n", - "51 223 as\n", - "67 46 a\n", - "38 278 handle\n", - "136 134 Yet\n", - "35 170 poetry\n", - "146 111 “Interface”)\n", - "158 132 suitable\n", - "187 189 example\n", - "159 200 would\n", - "33 241 that\n", - "178 213 nothing\n", - "62 78 critically\n", - "166 205 of\n", - "169 42 more\n", - "122 154 itself\n", - "187 278 formal\n", - "85 59 ”Chapter\n", - "35 104 themselves\n", - "145 64 states\n", - "37 85 or\n", - "81 226 that\n", - "19 253 \n", - "157 55 string\n", - "187 125 semantic\n", - "142 224 transformation\n", - "115 3 the\n", - "98 46 Wesley\n", - "61 202 a\n", - "178 32 in\n", - "110 211 command\n", - "169 240 be\n", - "166 82 symbols\n", - "34 192 languages\n", - "30 68 is\n", - "46 172 that\n", - "3 276 “natural\n", - "123 242 computer\n", - "100 123 common\n", - "162 248 that\n", - "140 31 it\n", - "9 146 are\n", - "165 10 in\n", - "132 271 control\n", - "173 276 But\n" + "84 58 computing\n", + "173 112 programming\n", + "113 255 processing\n", + "102 115 programming\n", + "145 38 nothing\n", + "54 71 programming\n", + "106 139 programming\n", + "107 10 programming\n", + "49 84 programming\n", + "8 188 expressing\n", + "158 63 programming\n", + "124 257 anything\n", + "39 8 understanding\n", + "121 221 programming\n", + "91 127 programming\n", + "12 170 understanding\n", + "71 47 programming\n", + "17 33 nothing\n", + "36 280 programming\n", + "175 112 typing\n", + "173 275 thinking\n", + "69 217 involving\n", + "29 274 meaning\n", + "122 223 meaning\n", + "75 45 meaning\n", + "104 255 programming\n", + "94 172 Turing\n", + "48 181 programming\n", + "29 107 programming\n", + "72 179 speaking\n", + "185 238 programming\n", + "71 214 Nothing\n", + "25 279 programming\n", + "76 255 thinking\n", + "31 152 programming\n", + "26 237 denoting\n", + "161 56 storing\n", + "6 170 transmitting\n", + "70 38 “programming\n", + "5 112 indicating\n", + "156 188 giving\n", + "56 238 passing\n", + "142 37 accepting\n", + "109 92 trading\n", + "163 161 Writing\n", + "1 163 programming\n", + "157 1 phrasing\n", + "93 161 layering\n", + "61 170 nothing\n", + "62 162 processing\n", + "152 19 string\n", + "47 259 computing\n", + "63 69 reshaping\n", + "71 144 data—including\n", + "187 156 writing\n", + "156 227 consisting\n", + "125 119 meaning\n", + "68 45 writing\n", + "123 18 dragging\n", + "72 153 encoding\n", + "53 209 expressing\n", + "31 273 flying\n", + "17 32 programming\n", + "166 140 programming\n", + "167 117 programming\n", + "42 214 programming\n", + "144 271 encoding\n", + "131 255 understanding\n", + "133 2 programming\n", + "7 66 programming\n", + "124 206 involving\n", + "166 46 writing\n", + "158 135 thinking\n", + "104 237 understanding\n", + "18 206 amusing\n", + "11 97 according\n", + "9 169 Designing\n", + "28 199 According\n", + "152 205 writing\n", + "97 274 surprising\n", + "49 92 Reading\n" ] } ], "source": [ - "# Draw on the canvas\n", - "for n in range(100):\n", + "# Another bag-of-words: word selections from Words of the Future\n", + "import os\n", + "import random\n", + "\n", + "bag = []\n", + "filenames = []\n", + "\n", + "folder = 'txt/words-for-the-future/'\n", + "for file in os.listdir(folder):\n", + " # print(folder+file)\n", + " txt = open('txt/language.txt', 'r').read()\n", + " words = txt.split()\n", + " bag += words\n", + " filenames.append(file) # We will use this for the caption\n", + "\n", + "# print(bag)\n", + "\n", + "# Select all the words that end on \"ing\" and draw them on the canvas\n", + "for word in words:\n", + " word = word.strip(',/\\\\!?;:\"\\'.') # \"clean up\" the words\n", " x = random.randint(0, 190)\n", " y = random.randint(0, 280)\n", - " word = random.choice(words).strip(',.')\n", - " print(x, y, word)\n", - " c.drawString(x*mm, y*mm, word)" + " if word.endswith('ing'):\n", + " print(x, y, word)\n", + " c.drawString(x*mm, y*mm, word)\n", + "\n", + "# Add a small caption\n", + "c.setFont('Courier', 10)\n", + "c.setFillColor(blue)\n", + "filenames_str = ', '.join(filenames)\n", + "c.drawCentredString(105*mm, 290*mm, 'Random words from: {f} (Words for the Future)'.format(f=filenames_str))\n", + "\n", + "# Save the PDF!\n", + "c.save()" ] }, { @@ -221,50 +266,6 @@ "outputs": [], "source": [] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 273, - "metadata": {}, - "outputs": [], - "source": [ - "# Add a small caption\n", - "c.setFont('Courier', 10)\n", - "c.setFillColor(blue)\n", - "c.drawCentredString(105*mm, 285*mm, 'Random words from Language and Software Studies, by Florian Cramer (2005)')" - ] - }, - { - "cell_type": "code", - "execution_count": 274, - "metadata": {}, - "outputs": [], - "source": [ - "# Save the PDF!\n", - "#c.showPage()\n", - "c.save()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": null, diff --git a/reportlab-cheatsheet.ipynb b/reportlab-cheatsheet.ipynb index ed91edf..cba6bdc 100644 --- a/reportlab-cheatsheet.ipynb +++ b/reportlab-cheatsheet.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -24,13 +24,13 @@ "source": [ "# ReportLab PDF Library\n", "\n", - "![](data:image/jpeg;base64,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)\n", + "![](data:image/jpeg;base64,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) ![](data:image/gif;base64,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)\n", "\n", "What is the ReportLab PDF Library?\n", "\n", - "This is a software library that lets you directly create documents in Adobe's Portable Document Format (PDF)using the Python programming language. It also creates charts and data graphics in various bitmap and vectorformats as well as PDF.\n", + "This is a software library that lets you directly create documents in Adobe's Portable Document Format (PDF)using the Python programming language. \n", "\n", - "https://www.reportlab.com/docs/reportlab-userguide.pdf" + "*tip*: the Reportlab Userguide, https://www.reportlab.com/docs/reportlab-userguide.pdf" ] }, { @@ -42,112 +42,18 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mInit signature:\u001b[0m\n", - "\u001b[0mCanvas\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpagesize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mbottomup\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpageCompression\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0minvariant\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mverbosity\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mencrypt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcropMarks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpdfVersion\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0menforceColorSpace\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0minitialFontName\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0minitialFontSize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0minitialLeading\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcropBox\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0martBox\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mtrimBox\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mbleedBox\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\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", - "This class is the programmer's interface to the PDF file format. Methods\n", - "are (or will be) provided here to do just about everything PDF can do.\n", - "\n", - "The underlying model to the canvas concept is that of a graphics state machine\n", - "that at any given point in time has a current font, fill color (for figure\n", - "interiors), stroke color (for figure borders), line width and geometric transform, among\n", - "many other characteristics.\n", - "\n", - "Canvas methods generally either draw something (like canvas.line) using the\n", - "current state of the canvas or change some component of the canvas\n", - "state (like canvas.setFont). The current state can be saved and restored\n", - "using the saveState/restoreState methods.\n", - "\n", - "Objects are \"painted\" in the order they are drawn so if, for example\n", - "two rectangles overlap the last draw will appear \"on top\". PDF form\n", - "objects (supported here) are used to draw complex drawings only once,\n", - "for possible repeated use.\n", - "\n", - "There are other features of canvas which are not visible when printed,\n", - "such as outlines and bookmarks which are used for navigating a document\n", - "in a viewer.\n", - "\n", - "Here is a very silly example usage which generates a Hello World pdf document.\n", - "\n", - "Example:: \n", - "\n", - " from reportlab.pdfgen import canvas\n", - " c = canvas.Canvas(\"hello.pdf\")\n", - " from reportlab.lib.units import inch\n", - " # move the origin up and to the left\n", - " c.translate(inch,inch)\n", - " # define a large font\n", - " c.setFont(\"Helvetica\", 80)\n", - " # choose some colors\n", - " c.setStrokeColorRGB(0.2,0.5,0.3)\n", - " c.setFillColorRGB(1,0,1)\n", - " # draw a rectangle\n", - " c.rect(inch,inch,6*inch,9*inch, fill=1)\n", - " # make text go straight up\n", - " c.rotate(90)\n", - " # change color\n", - " c.setFillColorRGB(0,0,0.77)\n", - " # say hello (note after rotate the y coord needs to be negative!)\n", - " c.drawString(3*inch, -3*inch, \"Hello World\")\n", - " c.showPage()\n", - " c.save()\n", - "\u001b[0;31mInit docstring:\u001b[0m\n", - "Create a canvas of a given size. etc.\n", - "\n", - "You may pass a file-like object to filename as an alternative to\n", - "a string.\n", - "For more information about the encrypt parameter refer to the setEncrypt method.\n", - "\n", - "Most of the attributes are private - we will use set/get methods\n", - "as the preferred interface. Default page size is A4.\n", - "cropMarks may be True/False or an object with parameters borderWidth, markColor, markWidth\n", - "and markLength\n", - "\n", - "if enforceColorSpace is in ('cmyk', 'rgb', 'sep','sep_black','sep_cmyk') then one of\n", - "the standard _PDFColorSetter callables will be used to enforce appropriate color settings.\n", - "If it is a callable then that will be used.\n", - "\u001b[0;31mFile:\u001b[0m ~/.local/lib/python3.7/site-packages/reportlab/pdfgen/canvas.py\n", - "\u001b[0;31mType:\u001b[0m type\n", - "\u001b[0;31mSubclasses:\u001b[0m \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "Canvas?" ] }, { "cell_type": "code", - "execution_count": 112, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -155,6 +61,26 @@ "c = Canvas(\"pdf/reportlab-cheatsheet.pdf\", pagesize=A4, bottomup=0)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Add a page\n", + "c.showPage()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Save the PDF\n", + "c.save()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -164,29 +90,16 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcircle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_cen\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_cen\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstroke\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfill\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\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 draw a cirle centered at (x_cen,y_cen) with radius r (special case of ellipse)\n", - "\u001b[0;31mFile:\u001b[0m ~/.local/lib/python3.7/site-packages/reportlab/pdfgen/canvas.py\n", - "\u001b[0;31mType:\u001b[0m method\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "c.circle?" ] }, { "cell_type": "code", - "execution_count": 114, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -195,29 +108,16 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwidth\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheight\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstroke\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfill\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\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 draws a rectangle with lower left corner at (x,y) and width and height as given.\n", - "\u001b[0;31mFile:\u001b[0m ~/.local/lib/python3.7/site-packages/reportlab/pdfgen/canvas.py\n", - "\u001b[0;31mType:\u001b[0m method\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "c.rect?" ] }, { "cell_type": "code", - "execution_count": 116, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -226,31 +126,16 @@ }, { "cell_type": "code", - "execution_count": 117, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mroundRect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwidth\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheight\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mradius\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstroke\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfill\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\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", - "Draws a rectangle with rounded corners. The corners are\n", - "approximately quadrants of a circle, with the given radius.\n", - "\u001b[0;31mFile:\u001b[0m ~/.local/lib/python3.7/site-packages/reportlab/pdfgen/canvas.py\n", - "\u001b[0;31mType:\u001b[0m method\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "c.roundRect?" ] }, { "cell_type": "code", - "execution_count": 118, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -259,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -282,33 +167,9 @@ }, { "cell_type": "code", - "execution_count": 120, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['Courier',\n", - " 'Courier-Bold',\n", - " 'Courier-BoldOblique',\n", - " 'Courier-Oblique',\n", - " 'Helvetica',\n", - " 'Helvetica-Bold',\n", - " 'Helvetica-BoldOblique',\n", - " 'Helvetica-Oblique',\n", - " 'Symbol',\n", - " 'Times-Bold',\n", - " 'Times-BoldItalic',\n", - " 'Times-Italic',\n", - " 'Times-Roman',\n", - " 'ZapfDingbats']" - ] - }, - "execution_count": 120, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Reportlab comes with a set of fonts\n", "c.getAvailableFonts()" @@ -316,7 +177,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -325,7 +186,7 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -339,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -348,7 +209,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -357,7 +218,7 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -380,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -397,7 +258,7 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -410,7 +271,7 @@ }, { "cell_type": "code", - "execution_count": 128, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -422,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -562,22 +423,6 @@ "outputs": [], "source": [] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Save PDF" - ] - }, - { - "cell_type": "code", - "execution_count": 130, - "metadata": {}, - "outputs": [], - "source": [ - "c.save()" - ] - }, { "cell_type": "code", "execution_count": null,