{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Weasyprint" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "from weasyprint import HTML, CSS\n", "from weasyprint.fonts import FontConfiguration" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "https://weasyprint.readthedocs.io/en/latest/tutorial.html" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# If you use @font-face in your stylesheet, you would need Weasyprint's FontConfiguration()\n", "font_config = FontConfiguration()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## HTML" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# small example HTML object\n", "html = HTML(string='

hello

')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or in this case let's use python + nltk to make a custom HTML page with parts of speech used as CSS classes..." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "ename": "ModuleNotFoundError", "evalue": "No module named 'nltk'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mnltk\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'txt/LIQUID1.txt'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mtxt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mwords\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnltk\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mword_tokenize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtxt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'nltk'" ] } ], "source": [ "import nltk\n", "\n", "with open('txt/LIQUID1.txt') as f:\n", " txt = f.read()\n", "words = nltk.word_tokenize(txt)\n", "tagged_words = nltk.pos_tag(words)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "content = ''\n", "content += '

LIQUID | Rachel Armstrong

'\n", "\n", "for word, tag in tagged_words:\n", " content+= f'{ word } '\n", " \n", "with open(\"txt/liquid.html\", \"w\") as f:\n", " f.write(f\"\"\"\n", "\n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", " Liquid\n", "\n", "\n", "{content}\n", "\n", "\"\"\")\n", "\n", "html = HTML(\"txt/liquid.html\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Saved to [language.html](txt/language.html). Fun fact: jupyter filters HTML pages that are displayed in the notebook. To see the HTML unfiltered, use an iframe (as below), or right-click and select Open in New Tab in the file list.\n", "\n", "Maybe useful evt. https://stackoverflow.com/questions/23358444/how-can-i-use-word-tokenize-in-nltk-and-keep-the-spaces" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "NB: The above HTML refers to the stylesheet [language.css](txt/language.css) (notice that the path is relative to the HTML page, so no need to say txt in the link)." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import IFrame\n", "IFrame(\"txt/liquid.html\", width=1024, height=600)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generating the PDF!\n", "\n", "Now let's let weasyprint do it's stuff! Write_pdf actually calculates the layout, behaving like a web browser to render the HTML visibly and following the CSS guidelines for page media (notice the special rules in the CSS that weasy print recognizes and uses that the browser does not). Notice that the CSS file gets mentioned again explicitly (and here we need to refer to its path relative to this folder)." ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "## If we had not linked the CSS in the HTML, you could specify it in this way\n", "# css = CSS(\"txt/language.css\", font_config=font_config)\n", "# html.write_pdf('txt/language.pdf', stylesheets=[css], font_config=font_config)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "css = CSS(\"txt/liquid.css\")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "html.write_pdf('liquid1.pdf', stylesheets=[css], font_config=font_config)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import IFrame\n", "IFrame(\"txt/liquid.pdf\", width=1024, height=600)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.3" } }, "nbformat": 4, "nbformat_minor": 4 }