PrettyTables.jl

repository·master·Indexed 19 days ago

https://github.com/ronisbr/prettytables.jl

A Julia package for printing matrices in customizable, aesthetically pleasing formats. It supports various backends, including a text-based output with styling via TextTableStyle and TextTableFormat, and an Excel backend using XLSX.jl. Key features include conditional cell highlighting with TextHighlighter, support for titles, subtitles, column labels, row groups, summary rows, and footnotes, as well as native Excel number-formatting and border customization.

Tokens
22.1K
Snippets
66
Records
81
Agent score
64%

What's inside PrettyTables.jl

  1. How TextHighlighter works

    master

    A TextHighlighter applies specific text styling to cells based on a predicate function. The predicate function takes three arguments: (data, i, j), where data is the matrix, i is the row index, and j is the column index. If the predicate returns true, the provided styling (e.g., using crayon) is applied to that cell.

    Example predicates:

    • (data, i, j) -> (j == 4) && (data[i, j] > 9): Highlights cells in the 4th column if their value is greater than 9.
    • (data, i, j) -> (i == 10): Highlights all cells in the 10th row.
    hl_p = TextHighlighter(
        (data, i, j) -> (j == 4) && (data[i, j] > 9),
        crayon"blue bold"
    )
  2. How Typst highlighters work

    master

    A TypstHighlighter allows you to apply conditional styling to specific cells. You can construct them in three ways:

    1. Fixed Decoration: TypstHighlighter(f::Function, decoration::Vector{Pair{String, String}})
    2. Tuple Decoration: TypstHighlighter(f::Function, decorations::NTuple{N, Pair{String, String}})
    3. Dynamic Decoration: TypstHighlighter(f::Function, fd::Function) where fd returns a Vector{Pair{String, String}}.

    Rules:

    • The function f(data, i, j) must return true if the cell at (i, j) should be highlighted.
    • If multiple highlighters match a cell, the first one in the highlighters vector is applied.
    • Highlighters receive the original, unformatted value from the data array, even if Formatters are used.
    • Styling Note: Attributes applied to text must use the text- prefix (e.g., "text-fill" => "white"). Other attributes apply to the cell itself (e.g., "fill" => "blue").
    # Highlight cells > 5 in red and < 5 in blue
    hl_gt5 = TypstHighlighter(
        (data, i, j) -> data[i, j] > 5,
        ["text-fill" => "red"]
    )
    
    hl_lt5 = TypstHighlighter(
        (data, i, j) -> data[i, j] < 5,
        ["text-fill" => "blue"]
    )
    
    pretty_table(data, backend = :typst, highlighters = [hl_gt5, hl_lt5])
  3. How TextTableStyle and TextTableFormat work

    master

    PrettyTables.jl uses two main abstractions to control the visual appearance of a table:

    1. TextTableStyle: Controls the styling of specific table elements, such as the first_line_column_label.
    2. TextTableFormat: Controls the structural layout and borders of the table, such as the borders type (e.g., text_table_borders__unicode_rounded).

    These are passed to the pretty_table function to customize the output.

    style = TextTableStyle(first_line_column_label = crayon"yellow bold")
    table_format = TextTableFormat(borders = text_table_borders__unicode_rounded)
    
    pretty_table(data; style=style, table_format=table_format)
  4. Apply cell highlighting with HtmlHighlighter

    master

    You can highlight specific cells by passing a Vector{HtmlHighlighter} to the highlighters keyword.

    An HtmlHighlighter consists of:

    • f::Function: A predicate f(data, i, j) that returns true if the cell at (i, j) should be highlighted.
    • fd::Function (optional): A function f(h, data, i, j) that returns a Vector{Pair{String, String}} of CSS properties to apply.

    Note on Formatters: If using highlighters with [Formatters], the data passed to the highlighter's predicate f is always the original, unformatted value.

    Note on Priority: If multiple highlighters match a cell, the first one in the vector is applied.

    # Highlight values > 5 in red and < 5 in blue
    hl_gt5 = HtmlHighlighter(
        (data, i, j) -> data[i, j] > 5,
        ["color" => "red"]
    )
    
    hl_lt5 = HtmlHighlighter(
        (data, i, j) -> data[i, j] < 5,
        ["color" => "blue"]
    )
    
    highlighters = [hl_gt5, hl_lt5]
    
    # Usage in pretty_table
    pretty_table(data, backend = :html, highlighters = highlighters)
  5. Understand the PrettyTables.jl table structure

    master

    PrettyTables.jl organizes tables into several logical sections that can be individually configured. A standard table consists of:

    • Title & Subtitle: Top-level headers.
    • Column Labels: The header row for data columns.
    • Stubhead: A label for the column containing row labels.
    • Row Number Column: An optional column for indexing rows.
    • Row Labels: A column providing names/labels for each row.
    • Data Cells: The main body of the table.
    • Row Group Labels: Spanning rows used to group sets of rows together.
    • Summary Rows: Rows at the bottom used for totals or aggregates.
    • Footnotes & Source Notes: Metadata at the bottom of the table.
  6. Configure table sections and styling

    master

    When calling pretty_table, you can pass several arguments to customize the output:

    Table Sections

    • title: A string for the table title.
    • subtitle: A string for the table subtitle.
    • column_labels: A nested array defining labels, including EmptyCells(n) and MultiColumn(n, "label").
    • row_group_labels: A dictionary or mapping (e.g., 1 => "Label") to group rows.
    • summary_rows: An array of functions (data, j) -> value to compute summary statistics for each column j.
    • summary_row_labels: Labels for the summary rows.
    • footnotes: A mapping (e.g., (:column_label, col, row) => "text") for table footnotes.

    Styling and Formatting

    • style: A TextTableStyle object to define colors/styles for components like column_label, subtitle, title, etc.
    • highlighters: An array of TextHighlighter objects that take a predicate (data, i, j) and a style.
    • table_format: A TextTableFormat object for structural settings (e.g., using @text__no_vertical_lines to remove vertical lines).
    • merge_column_label_cells: Controls how column labels are merged (e.g., :auto).
  7. Use the LaTeX backend in PrettyTables.jl

    master

    To generate LaTeX output, pass backend = :latex to the pretty_table function. When using this backend, you can use additional keywords to customize the output:

    • highlighters::Vector{LatexHighlighter}: A list of highlighters to apply to specific cells.
    • style::LatexTableStyle: Defines the LaTeX environments for various table elements (titles, labels, etc.).
    • table_format::LatexTableFormat: Defines the borders and lines (horizontal/vertical) of the table.
    pretty_table(data, backend = :latex, ...)
  8. Use the Markdown backend in PrettyTables.jl

    master

    To generate a table in Markdown format, pass the keyword backend = :markdown to the pretty_table function. When using this backend, you can use several additional keywords to control the output:

    • allow_markdown_in_cells::Bool: Enables markdown code within cell content. (Default: false)
    • highlighters::Vector{MarkdownHighlighter}: A list of highlighters to apply to specific cells.
    • line_breaks::Bool: Replaces \n in cell content with <br>. (Default: false)
    • style::MarkdownTableStyle: Configures the visual style of various table elements.
    • table_format::MarkdownTableFormat: Configures the structural layout of the Markdown table.
    pretty_table(data, backend = :markdown, ...)
  9. Use PrettyTables.jl to print formatted tables

    master

    PrettyTables.jl allows you to print matrices with customizable sections, styles, and highlighters. You can define column_labels (including sub-labels), TextTableStyle for header styling, TextHighlighter for conditional cell formatting, and TextTableFormat to define border types (e.g., using Unicode characters).

    using PrettyTables
    
    data = hcat(0:1:20, ones(21), 0:1:20, 0.5.*(0:1:20).^2)
    
    column_labels = [
        ["Time", "Acceleration", "Velocity", "Distance"],
        [ "[s]",     "[m / s²]",  "[m / s]",      "[m]"]
    ]
    
    # Define conditional highlighting
    hl_p = TextHighlighter(
        (data, i, j) -> (j == 4) && (data[i, j] > 9),
        crayon"blue bold"
    )
    
    # Define table style
    style = TextTableStyle(first_line_column_label = crayon"yellow bold")
    
    # Define border format
    table_format = TextTableFormat(borders = text_table_borders__unicode_rounded)
    
    # Generate the table string
    str = pretty_table(
        String,
        data;
        color         = true,
        column_labels = column_labels,
        style         = style,
        highlighters  = [hl_p],
        table_format  = table_format
    )
  10. Generate basic Markdown tables with `pretty_table`

    master

    To generate a Markdown table, use the pretty_table function and set the backend keyword to :markdown. You can provide custom column headers by passing a vector of strings to the column_labels keyword.

    using PrettyTables, Markdown
    
    A = Any[
        1    false      1.0     0x01
        2     true      2.0     0x02
        3    false      3.0     0x03
        4     true      4.0     0x04
        5    false      5.0     0x05
        6     true      6.0     0x06
    ]
    
    # Basic table
    table = pretty_table(String, A; backend = :markdown)
    
    # Table with custom column labels
    table = pretty_table(
        String,
        A;
        backend = :markdown,
        column_labels = ["ID", "Flag", "Value", "Hex"]
    )
  11. Use the Typst backend in PrettyTables.jl

    master

    To generate Typst code instead of standard text/markdown, pass backend = :typst to the pretty_table function.

    Note on Cell Content: By default, cell content is always escaped. If you need to pass raw Typst components as cell content, load the Typstry.jl package and pass the cell content as a TypstString. This prevents escaping and treats the content as raw Typst code.

    pretty_table(data, backend = :typst)