/
cell_parse.jl
152 lines (126 loc) · 5.18 KB
/
cell_parse.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
# ==============================================================================
#
# Functions to parse the table cells in text back-end.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
"""
_parse_cell_text(cell::T; kwargs...)
Parse the table cell `cell` of type `T`. This function must return:
* A vector of `String` with the parsed cell text, one component per line.
* A vector with the length of each parsed line.
* The necessary width for the cell.
"""
function _parse_cell_text(cell;
autowrap::Bool = true,
cell_data_type::DataType = Nothing,
cell_first_line_only::Bool = false,
column_width::Integer = -1,
compact_printing::Bool = true,
limit_printing::Bool = true,
linebreaks::Bool = false,
renderer::Union{Val{:print}, Val{:show}} = Val(:print),
kwargs...)
isstring = cell_data_type <: AbstractString
# Convert to string using the desired renderer.
cell_vstr = _render_text(renderer, cell,
compact_printing = compact_printing,
isstring = isstring,
limit_printing = limit_printing,
linebreaks = linebreaks || cell_first_line_only)
# Check if we must autowrap the text.
autowrap && (cell_vstr = _str_autowrap(cell_vstr, column_width))
if cell_first_line_only
cell_vstr = [first(cell_vstr)]
cell_lstr = [textwidth(first(cell_vstr))]
cell_width = first(cell_lstr)
else
cell_lstr = textwidth.(cell_vstr)
cell_width = maximum(cell_lstr)
end
return cell_vstr, cell_lstr, cell_width
end
function _parse_cell_text(cell::Markdown.MD;
column_width::Integer = -1,
linebreaks::Bool = false,
has_color::Bool = true,
kwargs...)
# The maximum size for Markdowns cells is 80.
column_width ≤ 0 && (column_width = 80)
# Render Markdown
# ==========================================================================
# First, we need to render the Markdown with all the colors.
str = sprint(Markdown.term, cell, column_width; context = :color => true)
# Now, we need to remove all ANSI escape sequences to count the printable
# characters.
#
# This regex was obtained at:
#
# https://stackoverflow.com/questions/14693701/how-can-i-remove-the-ansi-escape-sequences-from-a-string-in-python
#
str_nc = replace(str, r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])" => "")
if !linebreaks
str_nc = replace(str_nc, "\n" => "\\n")
cell_width = textwidth(str_nc)
if !has_color
return [str_nc], [cell_width], cell_width
else
str = replace(str, "\n" => "\\n")
return [str], [cell_width], cell_width
end
else
# Obtain the number of lines and the maximum number of used columns.
tokens_nc = split(str_nc, '\n')
lines = length(tokens_nc)
max_cols = maximum(textwidth.(tokens_nc))
num_chars = textwidth.(tokens_nc)
if !has_color
return tokens_nc, num_chars, max_cols
else
tokens = split(str, '\n')
_reapply_ansi_format!(tokens)
return tokens, num_chars, max_cols
end
end
end
@inline _parse_cell_text(cell::Missing; kwargs...) = ["missing"], [7], 7
@inline _parse_cell_text(cell::Nothing; kwargs...) = ["nothing"], [7], 7
@inline _parse_cell_text(cell::UndefInitializer; kwargs...) = ["#undef"], [6], 6
"""
_process_cell_text(data::Any, i::Int, j::Int, data_cell::Bool, data_str::String, data_len::Int, col_width::Int, crayon::Crayon, alignment::Symbol, highlighters::Tuple)
Process the cell by applying the right alignment and also verifying the
highlighters.
"""
function _process_cell_text(data::Any,
i::Int,
j::Int,
data_cell::Bool,
data_str::String,
data_len::Int,
col_width::Int,
crayon::Crayon,
alignment::Symbol,
highlighters::Tuple)
if data_cell
# Check for highlighters.
for h in highlighters
if h.f(_getdata(data), i, j)
crayon = h.fd(h, _getdata(data), i, j)
break
end
end
# For Markdown cells, we will overwrite alignment and highlighters.
if isassigned(data, i, j) && (data[i,j] isa Markdown.MD)
alignment = :l
crayon = Crayon()
end
end
# Align the string to be printed.
data_str, data_len = _str_aligned(data_str, alignment, col_width, data_len)
# Add spacing.
data_str = " " * data_str * " "
data_len += 2
return data_str, data_len, crayon
end