There is foreach//2 and foreach//3 in library(dcg/high_order). Here is a naive example with the two-argument version, without a separator:
:- use_module(library(http/html_write)).
:- use_module(library(dcg/high_order)).
author('Stephen King').
author('Gore Vidal').
author('Marja Kekäläinen').
author_list --> html(ul(\authors)).
authors --> foreach(author(A), html(li(A))).
This converts the table into a list of items.
?- phrase(author_list, L), print_html(L).
<ul>
<li>Stephen King</li>
<li>Gore Vidal</li>
<li>Marja Kekäläinen</li>
</ul>
L = [nl(1), <, ul, >, nl(1), nl(1), <, li, >|...].