Skip to content

Commit 0f09721

Browse files
authored
Add PT tests and missing PrettyTables funs. (#1796)
1 parent 507d9fe commit 0f09721

8 files changed

Lines changed: 617 additions & 45 deletions

File tree

src/GMT.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,8 @@ using GMT.Laszip
427427
#arrows([0 8.2 0 6], limits=(-2,4,0,9), arrow=(len=2,stop=1,shape=0.5,fill=:red), axis=:a, pen="6p");
428428
theme()
429429
#rescale(mat2img(rand(UInt16, 16,16,3)))
430-
plot(rand(5,2))
431430
GMT.finish_PS_nested(Dict{Symbol, Any}(), ["psbasemap -Rd -JX15c/0 -Baf -BWSen"])
431+
plot(rand(5,2))
432432
resetGMT()
433433
end
434434

src/PrettyTables.jl

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -829,15 +829,8 @@ function _print_table_with_text_back_end(
829829

830830
# -- Column Alignment Regex ------------------------------------------------------------
831831

832-
_apply_alignment_anchor_regex!(ptable, table_str, actual_columns_width,
833-
# Configurations.
834-
alignment_anchor_fallback,
835-
alignment_anchor_fallback_override,
836-
alignment_anchor_regex,
837-
columns_width,
838-
maximum_columns_width,
839-
minimum_columns_width
840-
)
832+
_apply_alignment_anchor_regex!(ptable, table_str, actual_columns_width, alignment_anchor_fallback,
833+
alignment_anchor_fallback_override, alignment_anchor_regex, columns_width, maximum_columns_width, minimum_columns_width)
841834

842835
# If the user wants all the columns with the same size, select the larger.
843836
if equal_columns_width
@@ -863,8 +856,7 @@ function _print_table_with_text_back_end(
863856
# -- Process the Title -----------------------------------------------------------------
864857

865858
title_tokens = _tokenize_title(title, display.size[2], table_width,
866-
title_alignment, title_autowrap, title_same_width_as_table
867-
)
859+
title_alignment, title_autowrap, title_same_width_as_table)
868860

869861
# == Print the Table ===================================================================
870862

@@ -1223,6 +1215,61 @@ function _print_title!(display::Display, title_tokens::Vector{String})
12231215
return nothing
12241216
end
12251217

1218+
function _str_autowrap(tokens_raw::Vector{String}, width::Int = 0)
1219+
width <= 0 && error("If `autowrap` is true, then the width must not be positive.")
1220+
tokens = String[]
1221+
1222+
for token in tokens_raw
1223+
sub_tokens = String[]
1224+
length_tok = length(token)
1225+
1226+
# Get the list of valid indices to handle UTF-8 strings. In this case, the n-th
1227+
# character of the string can be accessed by `token[tok_ids[n]]`.
1228+
tok_ids = collect(eachindex(token))
1229+
1230+
if length_tok > width
1231+
# First, let's analyze from the beginning of the token up to the field width.
1232+
#
1233+
# k₀ is the character that will start the sub-token.
1234+
# k₁ is the character that will end the sub-token.
1235+
k₀ = 1
1236+
k₁ = k₀ + width - 1
1237+
1238+
while k₀ <= length_tok
1239+
# Check if the remaining string fit in the available space.
1240+
if k₁ == length_tok
1241+
push!(sub_tokens, token[tok_ids[k₀:k₁]])
1242+
1243+
else
1244+
# If the remaining string does not fit into the available space, then we
1245+
# search for spaces to crop.
1246+
Δ = 0
1247+
for k = k₁:-1:k₀
1248+
if token[tok_ids[k]] == ' '
1249+
# If a space is found, then select `k₁` as this character and
1250+
# use `Δ` to remove it when printing, so that we hide the space.
1251+
k₁ = k
1252+
Δ = 1
1253+
break
1254+
end
1255+
end
1256+
1257+
push!(sub_tokens, token[tok_ids[k₀:k₁-Δ]])
1258+
end
1259+
1260+
# Move to the next analysis window.
1261+
k₀ = k₁+1
1262+
k₁ = clamp(k₀ + width - 1, 0, length_tok)
1263+
end
1264+
push!(tokens, sub_tokens...)
1265+
else
1266+
push!(tokens, token)
1267+
end
1268+
end
1269+
1270+
return tokens
1271+
end
1272+
12261273
# Split the table title into tokens considering the line break character.
12271274
function _tokenize_title(title::AbstractString, display_width::Int, table_width::Int,
12281275
# Configurations
@@ -2833,9 +2880,7 @@ function ProcessedTable(data::Any, header::Any;
28332880
end
28342881
end
28352882

2836-
if max_num_of_columns > 0
2837-
max_num_of_columns = min(max_num_of_columns, num_data_columns)
2838-
end
2883+
(max_num_of_columns > 0) && (max_num_of_columns = min(max_num_of_columns, num_data_columns))
28392884

28402885
return ProcessedTable(
28412886
data = data,
@@ -2860,15 +2905,11 @@ function _add_column!(ptable::ProcessedTable, new_column::AbstractVector, new_he
28602905
# data.
28612906
num_rows, ~ = _data_size(ptable)
28622907

2863-
if num_rows != length(new_column)
2864-
error("The size of the new column does not match the size of the table.")
2865-
end
2908+
(num_rows != length(new_column)) && error("The size of the new column does not match the size of the table.")
28662909

28672910
# The symbol cannot be `:__ORIGINAL_DATA__` because it is used to identified
28682911
# if a column is part of the original data.
2869-
if id == :__ORIGINAL_DATA__
2870-
error("The new column identification symbol cannot be `:__ORIGINAL_DATA__`.")
2871-
end
2912+
(id == :__ORIGINAL_DATA__) && error("The new column identification symbol cannot be `:__ORIGINAL_DATA__`.")
28722913

28732914
push!(ptable._additional_column_id, id)
28742915
push!(ptable._additional_data_columns, new_column)
@@ -3022,9 +3063,7 @@ end
30223063

30233064
# Parse the table `cell` of type `T` and return a vector of `String` with the parsed cell
30243065
# text, one component per line.
3025-
function _text_parse_cell(
3026-
@nospecialize(io::IOContext),
3027-
cell::Any;
3066+
function _text_parse_cell(@nospecialize(io::IOContext), cell::Any;
30283067
autowrap::Bool = true,
30293068
cell_data_type::DataType = Nothing,
30303069
cell_first_line_only::Bool = false,
@@ -3223,10 +3262,7 @@ function _get_column_alignment(ptable::ProcessedTable, j::Int)
32233262

32243263
# The apparently unnecessary conversion to `Symbol` avoids type instability.
32253264
ptable_data_alignment = ptable._data_alignment
3226-
3227-
alignment = ptable_data_alignment isa Symbol ?
3228-
Symbol(ptable_data_alignment) :
3229-
Symbol(ptable_data_alignment[jr])
3265+
alignment = ptable_data_alignment isa Symbol ? Symbol(ptable_data_alignment) : Symbol(ptable_data_alignment[jr])
32303266

32313267
return alignment
32323268
else

src/psxy.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function _common_plot_xyz(cmd0::String, arg1, caller::String, O::Bool, K::Bool,
2222

2323
arg2, arg3, arg4 = nothing, nothing, nothing
2424
N_args::Int = (arg1 === nothing) ? 0 : 1
25-
is_ternary = (caller == "ternary") ? true : false
25+
is_ternary = (caller == "ternary")
2626
if (is3D) gmt_proggy = (IamModern[1]) ? "plot3d " : "psxyz "
2727
elseif (is_ternary) gmt_proggy = (IamModern[1]) ? "ternary " : "psternary "
2828
else gmt_proggy = (IamModern[1]) ? "plot " : "psxy "
@@ -32,7 +32,7 @@ function _common_plot_xyz(cmd0::String, arg1, caller::String, O::Bool, K::Bool,
3232
cmd, isFV, caller, sub_module, gmt_proggy, opt_A, g_bar_fill, arg1 = parse_plot_callers(d, gmt_proggy, caller, is3D, O, arg1)
3333

3434
# --------------------- Check the grid2tri cases --------------------
35-
cmd, is_gridtri, arg1 = parse_grid2tri_case(d, cmd, caller, is3D, isFV, O, arg1)
35+
cmd, is_gridtri, arg1 = parse_grid2tri_case(d, cmd, caller, is3D, isFV, O, arg1) # FORCES RECOMPILE
3636

3737
isa(arg1, GMTdataset) && (arg1 = with_xyvar(d, arg1)) # See if we have a column request based on column names
3838
if ((val = hlp_desnany_int(d, [:decimate])) !== -999) # Asked for a clever data decimation?
@@ -63,7 +63,7 @@ function _common_plot_xyz(cmd0::String, arg1, caller::String, O::Bool, K::Bool,
6363
(isa(arg1, GMTdataset) && size(arg1,2) > 1 && !isempty(arg1.colnames)) && (CTRL.XYlabels[1] = arg1.colnames[1]; CTRL.XYlabels[2] = arg1.colnames[2])
6464
isa(arg1, Vector{<:GMTdataset}) && !isempty(arg1[1].colnames) && (CTRL.XYlabels[1] = arg1[1].colnames[1]; CTRL.XYlabels[2] = arg1[1].colnames[2])
6565
if (is_ternary) cmd, opt_J = parse_J(d, cmd, default=def_J)
66-
else cmd, opt_B, opt_J, opt_R = parse_BJR(d, cmd, caller, O, def_J)
66+
else cmd, opt_B, opt_J, opt_R = parse_BJR(d, cmd, caller, O, def_J) # FORCES RECOMPILE
6767
end
6868
# Current parse_B does not add a default -Baz when 3D AND -J has a projection. More or less fix that.
6969
if (is3D && opt_B != "" && !contains(opt_B, " -Bz"))
@@ -75,14 +75,14 @@ function _common_plot_xyz(cmd0::String, arg1, caller::String, O::Bool, K::Bool,
7575

7676
axis_equal = is_axis_equal(d) # See if the user asked for an equal aspect ratio
7777
cmd, opt_JZ = parse_JZ(d, cmd; O=O, is3D=is3D)
78-
cmd, = parse_common_opts(d, cmd, [:a :e :f :g :t :w :margin :params]; first=first)
78+
cmd, _ = parse_common_opts(d, cmd, [:a :e :f :g :t :w :margin :params]; first=first) # FORCES RECOMPILE
7979
cmd, opt_l = parse_l(d, cmd) # Parse this one (legend) aside so we can use it in classic mode
8080
cmd, opt_f = parse_f(d, cmd) # Parse this one (-f) aside so we can check against D.attrib
8181
cmd = parse_these_opts(cmd, d, [[:D :shift :offset], [:I :intens], [:N :no_clip :noclip], [:T]])
8282
parse_ls_code!(d::Dict) # Check for linestyle codes (must be before the GMTsyntax_opt() call)
8383
cmd = GMTsyntax_opt(d, cmd)[1] # See if an hardcore GMT syntax string has been passed by mk_styled_line!
8484
(is_ternary) && (cmd = add_opt(d, cmd, "M", [:M :dump]))
85-
opt_UVXY = parse_UVXY(d, "") # Need it separate to not risk to double include it.
85+
opt_UVXY = parse_UVXY(d, "") # FORCES RECOMPILE # Need it separate to not risk to double include it.
8686
cmd, opt_c = parse_c(d, cmd) # Need opt_c because we may need to remove it from double calls
8787

8888
if (isa(arg1, GDtype) && !contains(opt_f, "T") && !contains(opt_f, "t") && !contains(opt_R, "T") && !contains(opt_R, "t"))
@@ -632,9 +632,9 @@ function with_xyvar(d::Dict, arg1::GMTdataset, no_x::Bool=false)::Union{GMTdatas
632632

633633
function getcolvar(d::Dict, var::VMs)::Int
634634
((_val = find_in_dict(d::Dict, var)[1]) === nothing) && return 0
635-
!(isa(_val, Integer) || isa(_val, String) || isa(_val, Symbol)) && error("$(var) can only be an Int, a String or a Symbol but was a $(typeof(_val))")
636-
c = isa(_val, Integer) ? _val : ((_ind = findfirst(string(_val)::String .== arg1.colnames)) !== nothing ? _ind : 0)
637-
(c < 1 || c > size(arg1,2)) && error("$(var) Col name not found in GMTdataset col names or exceed col count.")
635+
!(isa(_val, Int) || isa(_val, StrSymb)) && error("$(_val) can only be an Int, a String or a Symbol but was a $(typeof(_val))")
636+
c::Int = isa(_val, Int) ? _val : ((_ind = findfirst(string(_val)::String .== arg1.colnames)) !== nothing ? _ind : 0)
637+
(c < 1 || c > size(arg1,2)) && error("$(_val) Col name not found in GMTdataset col names or exceed col count.")
638638
return c
639639
end
640640

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ using InteractiveUtils
2121
include("test_PT_column_width.jl")
2222
include("test_PT_default.jl")
2323
include("test_PT_table_lines.jl")
24+
include("test_PT_line_breaks.jl")
25+
include("test_PT_row_numbers.jl")
26+
include("test_PT_titles.jl")
2427

2528
include("test_avatars.jl")
2629
include("test_misc.jl")

test/test_PT_default.jl

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -296,17 +296,10 @@ end
296296
└────────────┘
297297
"""
298298

299-
result = pretty_table(
300-
String,
301-
vec;
302-
header = (["Header"], ["Sub-header"])
303-
)
299+
result = pretty_table(String, vec; header = (["Header"], ["Sub-header"]))
304300
@test result == expected
305301

306-
@test_throws Exception pretty_table(
307-
vec;
308-
header = ["1", "1"]
309-
)
302+
@test_throws Exception pretty_table( vec; header = ["1", "1"])
310303
end
311304

312305
@testset "Print missing, nothing, and #undef" begin
@@ -360,4 +353,17 @@ data = Any[1 false 1.0 0x01 ;
360353
io_result = String(take!(io))
361354

362355
@test io_result == ("\e[1F\e[2K"^(num_lines) * result)
356+
357+
GMT._next_string_state('a', :escape_state_begin)
358+
GMT._next_string_state('a', :escape_state_opening)
359+
GMT._next_string_state('a', :escape_state_1)
360+
GMT._next_string_state('a', :escape_state_2)
361+
GMT._next_string_state('a', :escape_state_3)
362+
GMT._next_string_state('a', :escape_hyperlink_opening)
363+
GMT._next_string_state('a', :escape_hyperlink_1)
364+
GMT._next_string_state('a', :escape_hyperlink_2)
365+
GMT._next_string_state('a', :escape_hyperlink_1)
366+
GMT._next_string_state('a', :escape_hyperlink_3)
367+
GMT._next_string_state('a', :escape_hyperlink_end)
368+
GMT._next_string_state('a', :escape_state_end)
363369
end

0 commit comments

Comments
 (0)