# \[ANN\] PrettyTables v3.0.0

**URL:** https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821
**Category:** Package Announcements
**Tags:** prettytables
**Created:** [August 25, 2025, 1:53am UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821 "2025-08-25T01:53:49Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 1:53am UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/1 "2025-08-25T01:53:49Z")

</div>

Hi!

Finally, I’ve completed the first release of PrettyTables.jl version 3! For anyone using this package, we can assume that everything in the API has changed (sorry about that :D). However, these breaking changes have very good reasons.

We now adhere to the table structure defined in R’s package GT. This results in a more coherent table design and a plethora of additional features, such as merging column labels (headers), adding summary rows, adding footnotes, and many more!

Since I am not a native English speaker, the keyword naming was previously inconsistent. I’ve taken great care to ensure coherence now. While the keyword names may be lengthy, they are highly meaningful.

We’ve introduced a true markdown backend, enhancing the package’s functionality.

The package has significantly improved its speed.

The internal structure has been streamlined, introducing a centralized printing state iterator. This simplifies the process of adding new backends, as each backend no longer needs to iterate through the table sections individually.

If anyone want a quick example, try this:

```julia
julia> matrix = [(i, j) for i in 1:3, j in 1:3];

julia> pretty_table(
    matrix;
    column_labels = [["Col. 1", MultiColumn(2, "Merged Column")], ["$i" for i in 1:3]],
    footnotes = [(:column_label, 1, 2) => "Footnote in column label", (:data, 2, 2) => "Footnote in data"],
    row_group_labels = [2 => "Row Group"],
    row_labels = ["Row $i" for i in 1:5],
    show_row_number_column = true,
    source_notes = "Source Notes",
    stubhead_label = "Rows",
    subtitle = "Table Subtitle",
    summary_rows = [(data, i) -> 10i, (data, i) -> 20i],
    title = "Table Title",
)

```

 ![Captura de Tela 2025-08-24 às 22.49.38](https://global.discourse-cdn.com/julialang/original/3X/a/3/a3b6a7804ec76c2eab5def6f8847935ae58af13d.png)

Please, expect some bugs and issues. If you find one, I appreciate if you can open a ticket in github!

In the coming days, I will submit a pull request to DataFrames.jl (@bkamins) to use the new version. In this case, it will have the same output, with minor improvements in edge cases. However, after the initial merge, we can begin incorporating the new features from PrettyTables.jl to enhance the output of DataFrames.jl.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [August 25, 2025, 2:03am UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/2 "2025-08-25T02:03:58Z")

</div>

That’s great news. Congratulations and thanks for all your work @Ronis_BR!

---

<div class="post-metadata">

### Author: ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)
#### Post date: [August 25, 2025, 2:12am UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/3 "2025-08-25T02:12:47Z")

</div>

I’ve already started using it. It’s really great!

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 25, 2025, 12:59pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/4 "2025-08-25T12:59:56Z")

</div>

Thank you @Ronis_BR !

How to reproduce `header_crayon` in the new release? I’ve tried playing with `TextTableStyle` without success. Appreciate your help:

> <https://github.com/JuliaEarth/GeoTables.jl/pull/146>
>
> Recently announced: https://discourse.julialang.org/t/ann-prettytables-v3-0-0/13…1821

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 2:17pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/5 "2025-08-25T14:17:18Z")

</div>

Hi @juliohm !

You can use `first_line_column_label` in `TextTableStyle` structure for the first line (which we called header) and `column_label` for the other lines (which we called subheaders).

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 2:19pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/6 "2025-08-25T14:19:15Z")

</div>

![Captura de Tela 2025-08-25 às 11.19.06](https://global.discourse-cdn.com/julialang/original/3X/f/5/f580c5ff06369687a482c9e849959a4f36d875dd.png)

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 25, 2025, 2:33pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/7 "2025-08-25T14:33:41Z")

</div>

@Ronis_BR I tried it, but in our use case we have multiple colors in the first row. The `first_line_column_label` only accepts a single color.

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 4:06pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/8 "2025-08-25T16:06:08Z")

</div>

Ah! So you want different colors for different column labels? I dropped this feature because I thought nobody was using it 😃

I will add it again.

---

<div class="post-metadata">

### Author: ![JoshuaLampert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshualampert/32/205964_2.png) [@JoshuaLampert](https://discourse.julialang.org/u/JoshuaLampert)
#### Post date: [August 25, 2025, 4:18pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/9 "2025-08-25T16:18:29Z")

</div>

I don’t know if this would be an alternative for your use case @juliohm, but I noticed that PrettyTables.jl v3 is compatible with StyledStrings.jl (which is pretty nice!). So different colors in the column labels would be possible using StyledStrings.jl

 ![prettytables](https://global.discourse-cdn.com/julialang/original/3X/8/c/8c535c6488925d05db413d7c3eb945230a8f1a4d.png)

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 5:06pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/10 "2025-08-25T17:06:04Z")

</div>

Thanks @JoshuaLampert ! I really forgot we could do this 😃 But yes, we have full support for StyledStrings.jl.

Anyway, to keep consistency with the previous version, I added the feature back as requested by @juliohm . It will be available in v3.0.1 (I am treating the lack of this feature as a bug). Now, we can do this:

 ![Captura de Tela 2025-08-25 às 14.04.44](https://global.discourse-cdn.com/julialang/original/3X/1/b/1b1bb8cc7e1f52bdc0077a516f82b2bfa61e8b56.png)

If you use both, StyledStrings.jl and the `style` keyword, the former has precedence.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [August 25, 2025, 5:28pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/11 "2025-08-25T17:28:32Z")

</div>

> [@Ronis\_BR](#):
>
> `stubhead_label = "Rows",`

Is this meant to be `subhead_label`?

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 5:29pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/12 "2025-08-25T17:29:59Z")

</div>

> [@StefanKarpinski](#):
>
> Is this meant to be `subhead_label`?

Actually no! I followed the naming convention in R’s package GT ([https://gt.rstudio.com](https://gt.rstudio.com)):

 ![Captura de Tela 2025-08-25 às 14.29.47](https://global.discourse-cdn.com/julialang/original/3X/c/2/c2e15b7e5bfd677fb15ed7abf1c5862e7d5317b2.png)

EDIT: Except for the “Spanner Column Label” which I called “Merged Column Label” because we can merge any adjacent column labels and instead of only the ones in the top of the hierarchy.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 25, 2025, 6:53pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/13 "2025-08-25T18:53:00Z")

</div>

Thank you @Ronis_BR @JoshuaLampert , everything works now in the `:text` backend 💯

Is there an equivalent in `HtmlTableStyle`? I noticed that it expects a `Vector{Pair}` instead.

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 6:59pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/14 "2025-08-25T18:59:21Z")

</div>

> [@juliohm](#):
>
> Is there an equivalent in `HtmlTableStyle`? I noticed that it expects a `Vector{Pair}` instead.

😃 I forgot that I have to change this in all backends! I will do that.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 25, 2025, 7:10pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/15 "2025-08-25T19:10:15Z")

</div>

I wonder if these style options are generic enough to become independent of backend. Perhaps a general `style = TableStyle(...)` could be introduced?

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 7:18pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/16 "2025-08-25T19:18:25Z")

</div>

Yes! This is something we can add! The idea is to have a general style that converts to a backend specific call. We just need to design a good API.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [August 25, 2025, 8:46pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/17 "2025-08-25T20:46:45Z")

</div>

TIL. Had never heard of a “stub head” before

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 25, 2025, 9:10pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/18 "2025-08-25T21:10:32Z")

</div>

@Ronis_BR I think @JoshuaLampert’s suggestion with styled strings is more general. It works for all backends. My PR is almost there, I am just having trouble to compare HTML output with special escape characters (colors):

> <https://github.com/JuliaEarth/GeoTables.jl/pull/146>
>
> Recently announced: https://discourse.julialang.org/t/ann-prettytables-v3-0-0/13…1821

Off-topic: do you know how to properly escape these color characters in `sprint` tests? The last test in the PR above is failing with a parsing error:

```html
<th style = "text-align: center; font-weight: bold;">\e[35m\e[1ma\e[39m\e[22m</th>

```

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 9:59pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/19 "2025-08-25T21:59:52Z")

</div>

> [@juliohm](#):
>
> @Ronis_BR I think @JoshuaLampert’s suggestion with styled strings is more general.

Yes, indeed! However, it is good to provide the other option for the case where the user cannot change the column labels for some reason.

> [@juliohm](#):
>
> Off-topic: do you know how to properly escape these color characters in `sprint` tests? The last test in the PR above is failing with a parsing error:

Can you please provide more detail? I am not sure if it is correct to mix ANSI escape sequences in HTML output.

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [August 25, 2025, 10:05pm UTC](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821/20 "2025-08-25T22:05:26Z")

</div>

@juliohm

I think I understood. To use StyledString in HTML we need to use `renderer = :show`. Furthermore I need to correct a bug 🙂 I will do this to allow you to use this approach.

[Next page](https://discourse.julialang.org/t/ann-prettytables-v3-0-0/131821.md?page=2)
