Skip to content

Commit f542a59

Browse files
authored
use at-latexrecipe for Latexify.jl (#49)
1 parent 309b60c commit f542a59

File tree

5 files changed

+147
-146
lines changed

5 files changed

+147
-146
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,22 @@ authors = ["Hendrik Ranocha <mail@ranocha.de> and contributors"]
44
version = "2.6.3-pre"
55

66
[deps]
7+
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
78
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
89
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
910
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
1011

1112
[compat]
13+
Latexify = "0.15"
1214
RecipesBase = "1"
1315
Requires = "1"
1416
julia = "1"
1517

1618
[extras]
17-
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
1819
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1920
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2021
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2122
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
2223

2324
[targets]
24-
test = ["Latexify", "Plots", "StaticArrays", "Test", "UnicodePlots"]
25+
test = ["Plots", "StaticArrays", "Test", "UnicodePlots"]

src/RootedTrees.jl

Lines changed: 4 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ module RootedTrees
55

66
using LinearAlgebra: dot
77

8+
using Latexify: Latexify
89
using RecipesBase: RecipesBase
910

10-
using Requires: @require
1111

12-
13-
export rootedtree, rootedtree!, RootedTreeIterator
12+
export RootedTree, rootedtree, rootedtree!, RootedTreeIterator
1413

1514
export butcher_representation
1615

@@ -119,70 +118,6 @@ function Base.show(io::IO, t::RootedTree{T}) where {T}
119118
end
120119

121120

122-
RecipesBase.@recipe function plot(t::RootedTree)
123-
# Compute x and y coordinates recursively
124-
width = 2.0
125-
height = 1.0
126-
x, y = _plot_coordinates(t, 0.0, 0.0, width, height)
127-
128-
# Series properties
129-
seriescolor --> :black
130-
markershape --> :circle
131-
markersize --> 6
132-
linewidth --> 2
133-
134-
# Geometric properties
135-
grid --> false
136-
ticks --> false
137-
foreground_color_border --> :white
138-
legend --> :bottomright
139-
140-
# We need to filter out `NaN` since these pollute `extrema`
141-
x_min, x_max = extrema(Iterators.filter(!isnan, x))
142-
if x_min x_max
143-
xlims --> (x_min - width/2, x_max + width/2)
144-
end
145-
y_min, y_max = extrema(Iterators.filter(!isnan, y))
146-
if y_min y_max
147-
ylims --> (y_min - height/2, y_max + height/2)
148-
end
149-
150-
# Annotations
151-
label --> "tree " * string(t.level_sequence)
152-
153-
x, y
154-
end
155-
156-
function _plot_coordinates(t::RootedTree, x_root::T, y_root::T,
157-
width::T, height::T) where {T}
158-
# Indicate a new line series by `NaN`
159-
nan = convert(T, NaN)
160-
x = [x_root]
161-
y = [y_root]
162-
163-
# Compute plot coordinates recursively
164-
subtr = subtrees(t)
165-
166-
# Distribute children uniformly in x and at equal y coordinates
167-
y_child = y_root + height
168-
num_children = length(subtr)
169-
distance = width * (num_children - 1) / 2
170-
171-
x_children = range(x_root - distance, x_root + distance, length=num_children)
172-
for idx in eachindex(subtr)
173-
x_child = x_children[idx]
174-
push!(x, nan, x_root, x_child)
175-
push!(y, nan, y_root, y_child)
176-
x_recursive, y_recursive = _plot_coordinates(subtr[idx],
177-
x_child, y_child, width / 3, height)
178-
append!(x, x_recursive)
179-
append!(y, y_recursive)
180-
end
181-
182-
return x, y
183-
end
184-
185-
186121
# comparison
187122

188123
"""
@@ -406,12 +341,6 @@ end
406341

407342

408343
function __init__()
409-
@require Latexify="23fbe1c1-3f47-55db-b15f-69d7ec21a316" begin
410-
using .Latexify: Latexify
411-
412-
Latexify._latexraw(t::RootedTree; kwargs...) = latexify(t)
413-
end
414-
415344
# canonical_representation!
416345
Threads.resize_nthreads!(CANONICAL_REPRESENTATION_BUFFER,
417346
Vector{Int}(undef, BUFFER_LENGTH))
@@ -1388,72 +1317,8 @@ function butcher_representation(t::RootedTree, normalize::Bool=true)
13881317
end
13891318

13901319

1391-
"""
1392-
latexify(t::RootedTree)
1393-
1394-
Return a LaTeX representation of the rooted tree `t`. This makes use of the
1395-
LaTeX package [forest](https://ctan.org/pkg/forest) and assumes that you use
1396-
the following LaTeX code in the preamble.
1397-
1398-
```
1399-
% Butcher trees, cf. https://tex.stackexchange.com/questions/283343/butcher-trees-in-tikz
1400-
\\usepackage{forest}
1401-
\\forestset{
1402-
*/.style={
1403-
delay+={append={[]},}
1404-
},
1405-
rooted tree/.style={
1406-
for tree={
1407-
grow'=90,
1408-
parent anchor=center,
1409-
child anchor=center,
1410-
s sep=2.5pt,
1411-
if level=0{
1412-
baseline
1413-
}{},
1414-
delay={
1415-
if content={*}{
1416-
content=,
1417-
append={[]}
1418-
}{}
1419-
}
1420-
},
1421-
before typesetting nodes={
1422-
for tree={
1423-
circle,
1424-
fill,
1425-
minimum width=3pt,
1426-
inner sep=0pt,
1427-
child anchor=center,
1428-
},
1429-
},
1430-
before computing xy={
1431-
for tree={
1432-
l=5pt,
1433-
}
1434-
}
1435-
}
1436-
}
1437-
\\DeclareDocumentCommand\\rootedtree{o}{\\Forest{rooted tree [#1]}}
1438-
```
1439-
1440-
# Examples
1441-
1442-
```jldoctest
1443-
julia> rootedtree([1, 2, 2]) |> RootedTrees.latexify |> println
1444-
\rootedtree[[][]]
1445-
1446-
julia> rootedtree([1, 2, 3, 3, 2]) |> RootedTrees.latexify |> println
1447-
\rootedtree[[[][]][]]
1448-
```
1449-
"""
1450-
function latexify(t::RootedTree)
1451-
if isempty(t)
1452-
return "\\varnothing"
1453-
end
1454-
list_representation = butcher_representation(t, false)
1455-
"\\rootedtree" * replace(list_representation, "τ" => "[]")
1456-
end
1320+
include("latexify.jl")
1321+
include("plots.jl")
14571322

14581323

14591324
end # module

src/latexify.jl

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
"""
3+
latexify(t::RootedTree)
4+
5+
Return a LaTeX representation of the rooted tree `t`. This makes use of the
6+
LaTeX package [forest](https://ctan.org/pkg/forest) and assumes that you use
7+
the following LaTeX code in the preamble.
8+
9+
```
10+
% Butcher trees, cf. https://tex.stackexchange.com/questions/283343/butcher-trees-in-tikz
11+
\\usepackage{forest}
12+
\\forestset{
13+
*/.style={
14+
delay+={append={[]},}
15+
},
16+
rooted tree/.style={
17+
for tree={
18+
grow'=90,
19+
parent anchor=center,
20+
child anchor=center,
21+
s sep=2.5pt,
22+
if level=0{
23+
baseline
24+
}{},
25+
delay={
26+
if content={*}{
27+
content=,
28+
append={[]}
29+
}{}
30+
}
31+
},
32+
before typesetting nodes={
33+
for tree={
34+
circle,
35+
fill,
36+
minimum width=3pt,
37+
inner sep=0pt,
38+
child anchor=center,
39+
},
40+
},
41+
before computing xy={
42+
for tree={
43+
l=5pt,
44+
}
45+
}
46+
}
47+
}
48+
\\DeclareDocumentCommand\\rootedtree{o}{\\Forest{rooted tree [#1]}}
49+
```
50+
51+
# Examples
52+
53+
```jldoctest
54+
julia> rootedtree([1, 2, 2]) |> RootedTrees.latexify |> println
55+
\rootedtree[[][]]
56+
57+
julia> rootedtree([1, 2, 3, 3, 2]) |> RootedTrees.latexify |> println
58+
\rootedtree[[[][]][]]
59+
```
60+
"""
61+
function latexify(t::RootedTree)
62+
if isempty(t)
63+
return "\\varnothing"
64+
end
65+
list_representation = butcher_representation(t, false)
66+
"\\rootedtree" * replace(list_representation, "τ" => "[]")
67+
end
68+
69+
70+
Latexify.@latexrecipe function _(t::RootedTree)
71+
return Latexify.LaTeXString(RootedTrees.latexify(t))
72+
end

src/plots.jl

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2+
RecipesBase.@recipe function plot(t::RootedTree)
3+
# Compute x and y coordinates recursively
4+
width = 2.0
5+
height = 1.0
6+
x, y = _plot_coordinates(t, 0.0, 0.0, width, height)
7+
8+
# Series properties
9+
seriescolor --> :black
10+
markershape --> :circle
11+
markersize --> 6
12+
linewidth --> 2
13+
14+
# Geometric properties
15+
grid --> false
16+
ticks --> false
17+
foreground_color_border --> :white
18+
legend --> :bottomright
19+
20+
# We need to filter out `NaN` since these pollute `extrema`
21+
x_min, x_max = extrema(Iterators.filter(!isnan, x))
22+
if x_min x_max
23+
xlims --> (x_min - width/2, x_max + width/2)
24+
end
25+
y_min, y_max = extrema(Iterators.filter(!isnan, y))
26+
if y_min y_max
27+
ylims --> (y_min - height/2, y_max + height/2)
28+
end
29+
30+
# Annotations
31+
label --> "tree " * string(t.level_sequence)
32+
33+
x, y
34+
end
35+
36+
function _plot_coordinates(t::RootedTree, x_root::T, y_root::T,
37+
width::T, height::T) where {T}
38+
# Indicate a new line series by `NaN`
39+
nan = convert(T, NaN)
40+
x = [x_root]
41+
y = [y_root]
42+
43+
# Compute plot coordinates recursively
44+
subtr = subtrees(t)
45+
46+
# Distribute children uniformly in x and at equal y coordinates
47+
y_child = y_root + height
48+
num_children = length(subtr)
49+
distance = width * (num_children - 1) / 2
50+
51+
x_children = range(x_root - distance, x_root + distance, length=num_children)
52+
for idx in eachindex(subtr)
53+
x_child = x_children[idx]
54+
push!(x, nan, x_root, x_child)
55+
push!(y, nan, y_root, y_child)
56+
x_recursive, y_recursive = _plot_coordinates(subtr[idx],
57+
x_child, y_child, width / 3, height)
58+
append!(x, x_recursive)
59+
append!(y, y_recursive)
60+
end
61+
62+
return x, y
63+
end

test/runtests.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ using Test
22
using StaticArrays
33
using RootedTrees
44

5-
using Latexify: latexify
5+
using RootedTrees.Latexify: latexify
66

77
using Plots: Plots, plot
88
Plots.unicodeplots()
@@ -97,7 +97,7 @@ end
9797
@test butcher_representation(t1) == "τ"
9898
latex_string = "\\rootedtree[]"
9999
@test RootedTrees.latexify(t1) == latex_string
100-
@test latexify(t1) == "\$" * latex_string * "\$"
100+
@test latexify(t1) == latex_string
101101
@test isempty(RootedTrees.subtrees(t1))
102102
@test RootedTrees.latexify(empty(t1)) == "\\varnothing"
103103

@@ -118,7 +118,7 @@ end
118118
@test butcher_representation(t2) == "[τ]"
119119
latex_string = "\\rootedtree[[]]"
120120
@test RootedTrees.latexify(t2) == latex_string
121-
@test latexify(t2) == "\$" * latex_string * "\$"
121+
@test latexify(t2) == latex_string
122122
@test RootedTrees.subtrees(t2) == [rootedtree([2])]
123123

124124
t3 = rootedtree([1, 2, 2])
@@ -131,7 +131,7 @@ end
131131
@test butcher_representation(t3) == "[τ²]"
132132
latex_string = "\\rootedtree[[][]]"
133133
@test RootedTrees.latexify(t3) == latex_string
134-
@test latexify(t3) == "\$" * latex_string * "\$"
134+
@test latexify(t3) == latex_string
135135
@test RootedTrees.subtrees(t3) == [rootedtree([2]), rootedtree([2])]
136136

137137
t4 = rootedtree([1, 2, 3])
@@ -144,7 +144,7 @@ end
144144
@test butcher_representation(t4) == "[[τ]]"
145145
latex_string = "\\rootedtree[[[]]]"
146146
@test RootedTrees.latexify(t4) == latex_string
147-
@test latexify(t4) == "\$" * latex_string * "\$"
147+
@test latexify(t4) == latex_string
148148
@test RootedTrees.subtrees(t4) == [rootedtree([2, 3])]
149149

150150
t5 = rootedtree([1, 2, 2, 2])

0 commit comments

Comments
 (0)