Code listing in Makie.jl figure

I’m interested in producing a figure using Makie with two sections. One section with a figure, another with a code listing (Julia code, of course). Has anyone tried this before / got any thoughts about how I could go about it?

In ancient times, I used Highlights.jl + Makie.text to create a plot with highlighted Julia code… I can take a look if that code is still around somewhere

2 Likes

That would be amazing, thank you!

Ok, this was interesting…Against all odds, I actually found the code sample…
It was almost 100% still working :open_mouth: But, Makie’s 1 color per char actually regressed, so I had to fix that: make it possible to have one color per glyph by SimonDanisch · Pull Request #1582 · JuliaPlots/Makie.jl · GitHub
But with that PR this works now:

using GLMakie


using Colors, Highlights
using Highlights.Format
using Highlights.Tokens
using Highlights.Themes

import Highlights.Themes: has_fg
css2color(str) = parse(RGBA{Float32}, string("#", str))
css2color(c::Themes.RGB) = RGBA{Float32}(c.r/255, c.g/255, c.b/255, 1.0)

function style2color(style, default)
    if has_fg(style)
        css2color(style.fg)
    else
        default
    end
end

function render_str(
        ctx::Format.Context, theme::Format.Theme
    )
    defaultcolor = if has_fg(theme.base)
        css2color(theme.base.fg)
    else
        RGBA(0f0, 0f0, 0f0, 1f0)
    end
    colormap = map(s-> style2color(s, defaultcolor), theme.styles)
    tocolor = Dict(zip(Tokens.__TOKENS__, colormap))
    colors = RGBA{Float32}[]
    io = IOBuffer()
    for token in ctx.tokens
        t = Tokens.__TOKENS__[token.value.value]
        str = SubString(ctx.source, token.first, token.last)
        print(io, str)
        append!(colors, fill(tocolor[t], length(str)))
        # push!(colors, tocolor[t])
    end
    String(take!(io)), colors
end


function highlight_text(src::AbstractString, theme = Themes.DefaultTheme)
    io = IOBuffer()
    render_str(
        Highlights.Compiler.lex(src, Lexers.JuliaLexer),
        Themes.theme(theme)
    )
end


src = """
function test(a, b)
    const a = sin(a) + 2.0
    return a 
end
"""

str, colors = highlight_text(src)

text(str, color=colors)

5 Likes

Incredible. Thanks again for sorting this out!

Out of interest, what’s Makie’s release cycle like? Will you issue a patch release when your PR is merged, or will it take a while for a new release with the PR included?

Usually we release patch releases after merging a PR… But the change to the mono repo slowed us down a bit - but this change should be released now and I hope to be faster going forward.

2 Likes

does not work, it seems to be no longer available. However setting to true where has_fg appears also does the work :smiley: