{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "LaTeX Render Debugging" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Rendering Behavior" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Some background notes:**\n", "The following operation prints the \"WARNING:...\" text, which might lead one to belive that the table being shown in the notebook is the LaTeX rendering, but it is actually the HTML implementation. As demonstrated later in this notebook, IP[y] executes both the \\_repr\\_html\\_() and the \\_repr\\_latex\\_() methods when rendering an object in the notebook, but (at least in all cases I've tested) displays the HTML rendering in the live notebook. The only way I've found to force IP[y] to render the LaTeX representaion is by running the 'nbconvert' utility on the notebook and rendering it to LaTeX." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from ipy_table import *\n", "table = make_table([(1,2),(3,4)])\n", "table" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "WARNING: include \\usepackage{array} on latex template\n", "\n" ] }, { "html": [ "
12
34
" ], "latex": [ "% Some macros could be added the first time table is created\n", "\\newlength{\\Oldarrayrulewidth}\n", "\\newcommand{\\thickline}[2]{%\n", " \\noalign{\\global\\setlength{\\Oldarrayrulewidth}{\\arrayrulewidth}}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{#1}}\\cline{#2}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{\\Oldarrayrulewidth}}}\n", "\n", "\\begin{tabular}{|l|l|}\n", "\\cline{1-2}1 & 2 \\\\ \\cline{1-2}\n", "3 & 4 \\\\ \\cline{1-2}\n", "\\end{tabular}" ], "metadata": {}, "output_type": "pyout", "prompt_number": 1, "text": [ "" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "To test the rendering behavior, we'll create an object that renders a table with the data \"1,2,3,4\" in its HTML render method and \"6,7,8,9\" in its LaTeX render method." ] }, { "cell_type": "code", "collapsed": false, "input": [ "table._repr_html_()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 2, "text": [ "'
12
34
'" ] } ], "prompt_number": 2 }, { "cell_type": "code", "collapsed": false, "input": [ "table._repr_latex_()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 3, "text": [ "'\\\\begin{tabular}{|l|l|}\\n\\\\cline{1-2}1 & 2 \\\\\\\\ \\\\cline{1-2}\\n3 & 4 \\\\\\\\ \\\\cline{1-2}\\n\\\\end{tabular}'" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "class render_test(object):\n", " def _repr_html_(self):\n", " print 'ENTRY: _repr_html_()'\n", " return r'''\n", " \n", "
12
34
'''\n", " def _repr_latex_(self):\n", " print 'ENTRY: _repr_latex_()'\n", " return r'''\\begin{tabular}{|l|l|} \n", " \\cline{1-2}6 & 7 \\\\ \n", " \\cline{1-2} 8 & 9 \\\\ \n", " \\cline{1-2} \n", " \\end{tabular}'''\n", "r=render_test()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "When we render the object we can see that:\n", "\n", "* Both rendering methods were executed by IP[y] (both \"ENTRY:...\" print logs were output)\n", "* The HTML rendering is shown in the notebook (the data \"1,2,3,4\" appears on-screen)\n", "* The LaTeX rendering is used when the notebook is converted to LaTeX format using nbconvert (the cell data \"6,7,8,9\" appears in the resulting LaTeX document)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "r" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "ENTRY: _repr_html_()\n", "ENTRY: _repr_latex_()\n" ] }, { "html": [ "\n", " \n", "
12
34
" ], "latex": [ "\\begin{tabular}{|l|l|} \n", " \\cline{1-2}6 & 7 \\\\ \n", " \\cline{1-2} 8 & 9 \\\\ \n", " \\cline{1-2} \n", " \\end{tabular}" ], "metadata": {}, "output_type": "pyout", "prompt_number": 5, "text": [ "<__main__.render_test at 0x5409710>" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the reading I've done, IP[y] is incapable of rendering tabular LaTeX data in the browser (which I believe stems from IP[y]'s use of MathJax and the omission of tabular support from that engine). Even though the attempt below to force IP[y] to render a tabular structure fails (in the browser it renders the source code in a box), the LaTeX table renders properly when the notebook is converted using nbconvert." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.display import Latex\n", "Latex(r'''\\begin{tabular}{|l|l|} \n", " \\cline{1-2}6 & 7 \\\\ \n", " \\cline{1-2} 8 & 9 \\\\ \n", " \\cline{1-2} \n", " \\end{tabular}''')" ], "language": "python", "metadata": {}, "outputs": [ { "latex": [ "\\begin{tabular}{|l|l|} \n", " \\cline{1-2}6 & 7 \\\\ \n", " \\cline{1-2} 8 & 9 \\\\ \n", " \\cline{1-2} \n", " \\end{tabular}" ], "metadata": {}, "output_type": "pyout", "prompt_number": 6, "text": [ "" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Conclusion:** The only way to validate the LaTeX rendering method is to convert notebooks to LaTeX documents and check the output. I've been using the command:\n", "\n", " ipython nbconvert --to latex --SphinxTransformer.author='Eric Moyer' \n", " --post PDF LaTeX_debugging.ipynb" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Implicit error suppression" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "IP[y] implicitly suppresses errors encountered when executing implicit rendering methods. That means that if you want to check whether render code is executing without a traceback then you need to call it explicitly. The following imlicit (and errant) code executes without a (reported) traceback:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "table=make_table([(1,2),(3,4)])\n", "table.set_cell_style(1, 1, color='ThisIsNotAValidColor')\n", "table" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
12
34
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 7, "text": [ "" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "When the same operation is called explicitly, the traceback is reported:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "######################\n", "# Uncomment the folowing line to generate a traceback.\n", "# Note that if you leave it uncommented and try to \"Run All\" cells \n", "# in the notebook, then executioin will stop at the traceback \n", "# (subsequent cells will not execute)\n", "\n", "#table._repr_latex_()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 20 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Issues with the current \\_repr\\_latex\\_() implementation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I haven't yet tested all possible style options, but I've run some cell color tests and the LaTeX rendering is not working properly." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Single Cell color" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the following example a single cell is set to Cyan. The color is defined but it doesn't appear to be applied to any cell. I've never worked with the LaTeX syntax before so I'll have to go educate myself. Nevertheless, LaTeX renders the table but without color (see PDF generated from LaTeX doc. The color appears in the browser/nbviewer but that is the HTML representation)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "table=make_table([(1,2),(3,4)])\n", "table.set_cell_style(1, 1, color='Cyan')\n", "print table._repr_latex_()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "WARNING: include \\usepackage{array} on latex template\n", "\n", "% Some macros could be added the first time table is created\n", "\\newlength{\\Oldarrayrulewidth}\n", "\\newcommand{\\thickline}[2]{%\n", " \\noalign{\\global\\setlength{\\Oldarrayrulewidth}{\\arrayrulewidth}}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{#1}}\\cline{#2}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{\\Oldarrayrulewidth}}}\n", "\n", "\\definecolor{Cyan}{rgb}{0,1,1}\n", "\n", "\\begin{tabular}{|l|l|}\n", "\\cline{1-2}1 & 2 \\\\ \\cline{1-2}\n", "3 & 4 \\\\ \\cline{1-2}\n", "\\end{tabular}\n" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "table" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
12
34
" ], "latex": [ "\\begin{tabular}{|l|l|}\n", "\\cline{1-2}1 & 2 \\\\ \\cline{1-2}\n", "3 & 4 \\\\ \\cline{1-2}\n", "\\end{tabular}" ], "metadata": {}, "output_type": "pyout", "prompt_number": 10, "text": [ "" ] } ], "prompt_number": 10 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Applying style after render clobbers macros" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If a table has been rendered once already,then the subsequent application of a style operation clears the macros (color definitions etc) normally appearing at the beginning of the LaTeX code." ] }, { "cell_type": "code", "collapsed": false, "input": [ "table=make_table([(1,2),(3,4)])\n", "table.set_cell_style(1, 1, color='Cyan')\n", "print table._repr_latex_()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "WARNING: include \\usepackage{array} on latex template\n", "\n", "% Some macros could be added the first time table is created\n", "\\newlength{\\Oldarrayrulewidth}\n", "\\newcommand{\\thickline}[2]{%\n", " \\noalign{\\global\\setlength{\\Oldarrayrulewidth}{\\arrayrulewidth}}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{#1}}\\cline{#2}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{\\Oldarrayrulewidth}}}\n", "\n", "\\definecolor{Cyan}{rgb}{0,1,1}\n", "\n", "\\begin{tabular}{|l|l|}\n", "\\cline{1-2}1 & 2 \\\\ \\cline{1-2}\n", "3 & 4 \\\\ \\cline{1-2}\n", "\\end{tabular}\n" ] } ], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "table.set_cell_style(0, 1, color='Cyan')\n", "print table._repr_latex_()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\\begin{tabular}{|l|>{\\columncolor{Cyan}}l|}\n", "\\cline{1-2}1 & 2 \\\\ \\cline{1-2}\n", "3 & 4 \\\\ \\cline{1-2}\n", "\\end{tabular}\n" ] } ], "prompt_number": 26 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Applicaiton of basic style causes rendering errors" ] }, { "cell_type": "code", "collapsed": false, "input": [ "table=make_table([(1,2),(3,4)])\n", "table.apply_theme('basic')\n", "print table._repr_latex_()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "WARNING: include \\usepackage{array} on latex template\n", "\n", "% Some macros could be added the first time table is created\n", "\\newlength{\\Oldarrayrulewidth}\n", "\\newcommand{\\thickline}[2]{%\n", " \\noalign{\\global\\setlength{\\Oldarrayrulewidth}{\\arrayrulewidth}}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{#1}}\\cline{#2}%\n", " \\noalign{\\global\\setlength{\\arrayrulewidth}{\\Oldarrayrulewidth}}}\n", "\n", "\\definecolor{Ivory}{rgb}{1,1,0}\n", "\\definecolor{LightGray}{rgb}{0.75,0.75,0.75}\n", "\n", "\\begin{tabular}{|>{\\columncolor{Ivory}}l|>{\\columncolor{Ivory}}l|}\n", "\\cline{1-2}\\textbf{1} & \\textbf{2} \\\\ \\cline{1-2}\n", "3 & 4 \\\\ \\cline{1-2}\n", "\\end{tabular}\n" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "######################\n", "# Uncomment the folowing line to render the table. The table\n", "# will render propery in the notebook (HTML) but will fail\n", "# the nbconvert conversion to LaTeX\n", "\n", "#table" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 31 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Success Criteria" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At the very least, a successful LaTeX render implementation will need to be capable of rendering the ipy_table-Reference notebook Without LaTex conversion errors (since that notebook contains examples of all ipy_table styles). That means that the command...\n", "\n", " ipython nbconvert --to latex --post PDF ipy_table-Reference.ipynb\n", " \n", "...should execute without error. Today it fails.\n", "\n", "At best, a successful implementation should render as many aspects of the HTML implementation as are possible in LaTeX's syntax. I'm not familiar with the details of the LaTeX syntax so I don't know how many of ipy_table's current capabilities may be unrenderable in LaTeX." ] } ], "metadata": {} } ] }