34
35:- module(swish_render_table,
36 [ term_rendering//3 37 ]). 38:- use_module(library(apply)). 39:- use_module(library(lists)). 40:- use_module(library(pairs)). 41:- use_module(library(dicts)). 42:- use_module(library(option)). 43:- use_module(library(http/html_write)). 44:- use_module(library(http/term_html)). 45:- use_module('../render'). 46
47:- register_renderer(table, "Render data as tables").
64term_rendering(Term, _Vars, Options) -->
65 { is_list_of_dicts(Term, _Rows, ColNames), !,
66 partition(is_header, Options, _HeaderOptions, Options1)
67 }, !,
68 html(div([ style('display:inline-block'),
69 'data-render'('List of terms as a table')
70 ],
71 [ table(class('render-table'),
72 [ \header_row(ColNames),
73 \rows(Term, Options1)
74 ])
75 ])).
76term_rendering(Term, _Vars, Options) -->
77 { is_list_of_terms(Term, _Rows, _Cols),
78 header(Term, Header, Options, Options1)
79 }, !,
80 html(div([ style('display:inline-block'),
81 'data-render'('List of terms as a table')
82 ],
83 [ table(class('render-table'),
84 [ \header_row(Header),
85 \rows(Term, Options1)
86 ])
87 ])).
88term_rendering(Term, _Vars, Options) -->
89 { is_list_of_lists(Term, _Rows, _Cols),
90 header(Term, Header, Options, Options1)
91 }, !,
92 html(div([ style('display:inline-block'),
93 'data-render'('List of lists as a table')
94 ],
95 [ table(class('render-table'),
96 [ \header_row(Header),
97 \rows(Term, Options1)
98 ])
99 ])).
100
101rows([], _) --> [].
102rows([H|T], Options) -->
103 { cells(H, Cells) },
104 html(tr(\row(Cells, Options))),
105 rows(T, Options).
106
107row([], _) --> [].
108row([H|T], Options) -->
109 html(td(\term(H, Options))),
110 row(T, Options).
111row([H|T], Options) -->
112 html(td(\term(H, []))),
113 row(T, Options).
114
115cells(Row, Cells) :-
116 is_list(Row), !,
117 Cells = Row.
118cells(Row, Cells) :-
119 is_dict(Row), !,
120 dict_pairs(Row, _Tag, Pairs),
121 pairs_values(Pairs, Cells).
122cells(Row, Cells) :-
123 compound(Row),
124 compound_name_arguments(Row, _, Cells).
131header(_, _, Options0, Options) :-
132 \+ option(header(_), Options0), !,
133 Options = Options0.
134header([Row|_], ColHead, Options0, Options) :-
135 partition(is_header, Options0, HeaderOptions, Options),
136 member(HeaderOption, HeaderOptions),
137 header(HeaderOption, Header),
138 generalise(Row, GRow),
139 generalise(Header, GRow), !,
140 header_list(Header, ColHead).
141
(0) :- !, fail.
143is_header(header(_)).
144is_header(header=_).
145
(header(H), H).
147header(header=H, H).
148
149generalise(List, VList) :-
150 is_list(List), !,
151 length(List, Len),
152 length(VList0, Len),
153 VList = VList0.
154generalise(Compound, VCompound) :-
155 compound(Compound), !,
156 compound_name_arity(Compound, Name, Arity),
157 compound_name_arity(VCompound0, Name, Arity),
158 VCompound = VCompound0.
159
(List, List) :- is_list(List), !.
161header_list(Compound, List) :-
162 Compound =.. [_|List].
169header_row(ColNames) -->
170 { var(ColNames) }, !.
171header_row(ColNames) -->
172 html(tr(class(hrow), \header_columns(ColNames))).
173
174header_columns([]) --> [].
175header_columns([H|T]) -->
176 html(th(\term(H, []))),
177 header_columns(T).
185is_list_of_terms(Term, Rows, Cols) :-
186 is_list(Term), Term \== [],
187 length(Term, Rows),
188 maplist(is_term_row(_Name, Cols), Term),
189 Cols > 0.
190
191is_term_row(Name, Arity, Term) :-
192 compound(Term),
193 compound_name_arity(Term, Name, Arity).
200is_list_of_dicts(Term, Rows, ColNames) :-
201 is_list(Term), Term \== [],
202 length(Term, Rows),
203 maplist(is_dict_row(ColNames), Term).
204
205is_dict_row(ColNames, Dict) :-
206 is_dict(Dict),
207 dict_keys(Dict, ColNames).
213is_list_of_lists(Term, Rows, Cols) :-
214 is_list(Term), Term \== [],
215 length(Term, Rows),
216 maplist(is_list_row(Cols), Term),
217 Cols > 0.
218
219is_list_row(Length, Term) :-
220 is_list(Term),
221 length(Term, Length)
SWISH table renderer
Render table-like data. */