PrettyTables.jl now has initial support for HTML output

Hi!

I just want to announce that I pushed a set of commits to make PrettyTables.jl support HTML output. I would like to have some feedback and help in testing (I am no HTML expert…). Notice that you will need to use master branch.

Initially, I thought I could have a generic function that can print to text and HTML. However, this is very difficult do accomplish due to the differences between both environments. For example, in HTML, you can change font family, but you cannot do that in text mode. Thus, I decided to have similar, but different configurations parameters for each back-end. This means that apart from the basic configuration, you cannot just change the back-end, you will need to change the configuration parameters as well. Maybe in the future we can design and API to translate between both.

Here is a screenshot of a Jupyter notebook using the HTML backend. Of course, you can also save the output to a .html file.

I tried to make this very configurable. You can virtually print the table anyway you like, because you can provide custom css to be added.

21 Likes

Maybe you can call your package

PrettyHTMLTables.jl

1 Like

PrettyTables.jl also has a text back-end (in fact it started as a way to pretty print tables to terminal).

2 Likes

Ronis,

I want you to know that I have incorporated your pretty table into my module

module PDFPs
    import Base: ==, +, -, *, /, \, ^, <, <=, %, Γ·, mod, fld, cld, floor, ceil
    import Base: float, inv, round, <<, >>
    import Base: sqrt, cbrt, show, factorial
    # Unfortunately getproperty slows down PDFP so we disable it from version 2.1.5
    # import Base: getproperty

    using PrettyTables, SpecialFunctions, ForwardDiff, LinearAlgebra, Statistics, Distributions
function prettytable1D(vector,label::String)
    len = length(vector)
    matrix = Array{Any,2}(undef,len,2);
    for row in 1:len
        matrix[row,1] = row - 1
        matrix[row,2] = vector[row]
    end
    pretty_table(matrix,["depth",label])
end

function prettytable2D(vector)
    len = length(vector)
    matrix = Array{Any,2}(undef,len,3);
    for row in 1:len
        matrix[row,1] = row - 1
        matrix[row,2] = vector[row][1]
        matrix[row,3] = vector[row][2]
    end
    pretty_table(matrix,["depth","x","y"])
end

result = PDFP_newtonRaphson_multifunc_multivariate(f,value,20,true,DiffMethod="Automatic",LogDict=logdict)

tracklog = logdict["tracklog"]
tracklog_string = PDFP_convertVecVectoString(tracklog)

println()
println("=== tracklog ===")
prettytable2D(tracklog_string)
=== tracklog ===
β”Œβ”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ depth β”‚                 x β”‚                  y β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     0 β”‚ 2.000000000000000 β”‚  3.000000000000000 β”‚
β”‚     1 β”‚ 1.499999999999999 β”‚  1.500000000000000 β”‚
β”‚     2 β”‚ 1.583333333333333 β”‚ 0.9166666666666665 β”‚
β”‚     3 β”‚ 1.675484094052559 β”‚ 0.8940179806362377 β”‚
β”‚     4 β”‚ 1.674148101652140 β”‚ 0.8959765160151239 β”‚
β”‚     5 β”‚ 1.674149228035889 β”‚ 0.8959774761302971 β”‚
β”‚     6 β”‚ 1.674149228035540 β”‚ 0.8959774761298381 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

=== vectordiff ===
β”Œβ”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ depth β”‚                      x β”‚                      y β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     0 β”‚    -0.5000000000000007 β”‚     -1.500000000000000 β”‚
β”‚     1 β”‚    0.08333333333333420 β”‚    -0.5833333333333335 β”‚
β”‚     2 β”‚    0.09215076071922585 β”‚   -0.02264868603042876 β”‚
β”‚     3 β”‚  -0.001335992400419135 β”‚   0.001958535378886226 β”‚
β”‚     4 β”‚   1.126383749322501E-6 β”‚   9.601151732034509E-7 β”‚
β”‚     5 β”‚ -3.489329826610390E-13 β”‚ -4.589578360097503E-13 β”‚
β”‚     6 β”‚ -9.286509053016300E-17 β”‚  4.969988818226068E-17 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

=== score ===
β”Œβ”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ depth β”‚                 score β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     0 β”‚     130.0000000000000 β”‚
β”‚     1 β”‚     6.250000000000003 β”‚
β”‚     2 β”‚    0.1205632716049392 β”‚
β”‚     3 β”‚  8.108508457272838E-5 β”‚
β”‚     4 β”‚ 3.159267906972166E-11 β”‚
β”‚     5 β”‚ 4.793890810000000E-24 β”‚
β”‚     6 β”‚ 1.600000000000000E-31 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1 Like

Wow! This is very nice :slight_smile: I am glad it was useful. Let me know if you need some feature or if you find a bug.

This is interesting.

I was working on adding support for Tables and DataFrames in AcuteML.

https://github.com/aminya/AcuteML.jl

But not for printing it as table, and instead for using the data itself, i.e. separating each column to a vector and making elements based on that.

However, if the user wants to print the data as a table I can use your package! (Custom Value Types Β· AcuteML.jl)

Does your package parse the html too? or it just exports?

2 Likes

Hi @Amin_Yahyaabadi !

The purpose of this package is just to print data that can be put in form of a table. Currently we can print to terminal (text) and now also to html (still under development). Thus, it has no capability to parse html data.

2 Likes

This is very nice. Do you plan to offer support for LaTeX tables as well?

2 Likes

Thanks! Yes, this will be the next step :slight_smile:

8 Likes

Sorry the number of replies, but I am very excited with the possibilities using HTML. For example, I could easily integrate the package ColorSchemes.jl to print a table highlighting the values with a colormap:

10 Likes

You’re the OP - fire away!

Also, it’s great you just demonstrated a ConditionalFormat capability, that’s awesome!
p.s. - have been using PrettyTables for a while, nice you’re continuing to develop it.

2 Likes

Nice! I am happy it is being useful :slight_smile: I will continue to develop it. It is helping me a lot to analyze data in my work. The next step after stabilization of HTML back-end is to add LaTeX. This will be awesome to construct tables for scientific papers.

4 Likes

I’d love to give this a try. I’m new to Julia but an experienced data science user in Python. And HTML table output has been a pain for me in the past.

How do I use master version? Do I git clone and the dev the repo?

Hi @venuur,

To use the master branch, just open Julia, hit ], and type dev PrettyTables. You can use the built-in doc system to get some info about the functions. Just hit ?, and then type pretty_table.

The HTML back-end is still under development, so expect rough edges, I would appreciate if you can give me feedback about bugs and/or features you would like :slight_smile:

2 Likes

Hi all, @Ronis_BR has been working with us in the Sublime Text 3: Worth a look! thread, to get a dynamic browser preview of the html output from PrettyTables.jl. We have it working, and the solution works fine without Sublime Text and just using the REPL plus the OpenSource Node app reload:

The key here is to instead of outputting the table to the REPL, to send it to a .html file. In the screenshot, there is a shell on the left side of monitor (quickly done using the Super(Win)+LeftArrow key). The shell has 2 tabs, one with the REPL running as show, and another with reload running. When you run reload -b while in the directory to which your .html file is written by PrettyTables, it launches a browser. Each time the html file is changed (due to changes in the REPL and new output), the browser automatically refreshes with the new output. The browser was placed on right side of monitor with Super(Win)+RightArrow key.


and, here’s the code if you want to run it. Be sure to use the Master branch, or the HTMLDecoration and other functionality won’t work!

## PrettyTables in REPL to Browser  - Workflow for Live-Reload
# ref: 
# The '-g' option in the npm install command installs the app globally
# $ sudo npm install -g reload                                          [1]
# /usr/bin/reload -> /usr/lib/node_modules/reload/bin/reload
# + reload@3.0.3
# added 50 packages from 53 contributors in 8.159s
# 
# pwd()
# "/home/e/Documents/eds2020_xps15/julia/workflow/html-st3"
# This is where HTML file will be saved by PrettyTables, alter as needed.
# Send the 3 line-output command to write the index.html file.
# Once file is present in directory, navigate to directory in a terminal shell.
# Enter following command to run 'reload' app and launch a browser with '-b'
# $ reload -b
#
# This is what it will look like when running, with a new line for each time index.html changes:
# ~/.../workflow/html-st3 >>> reload -b                                                                
# Reload web server:
# listening on port 8080
# monitoring dir /home/e/Documents/eds2020_xps15/julia/workflow/html-st3
# Server restarted  at 12:52:16
# Server restarted  at 12:52:48

using PrettyTables

t = 0:1:20;
data = hcat(t, ones(length(t))*1, 1*t, 0.5.*t.^2);
header = ["Time" "Acceleration" "Velocity" "Distance";
               "[s]"       "[m/sΒ²]"    "[m/s]"      "[m]"];

hl_v = HTMLHighlighter( (data,i,j)->(j == 3) && data[i,3] > 9, HTMLDecoration(color = "blue", font_weight = "bold"));
hl_p = HTMLHighlighter( (data,i,j)->(j == 4) && data[i,4] > 10, HTMLDecoration(color = "red"));
hl_e = HTMLHighlighter( (data,i,j)->data[i,1] == 10, HTMLDecoration(background = "gray", color = "white"));

# The below line outputs to the REPL. We skip this with the HTML output
# pretty_table(data, header, backend = :html, highlighters = (hl_e, hl_p, hl_v, hl_e))
# 
# After updating any code, highlight below 3-lines and ctrl-enter to send to REPL. HTML will refresh
open("index.html", "w") do f
pretty_table(f, data, header, backend = :html, highlighters = (hl_e, hl_p, hl_v, hl_e))
end

Thanks again for your work Ronis!! :+1:

3 Likes