22
33import java .util .AbstractMap .SimpleEntry ;
44import java .util .ArrayDeque ;
5+ import java .util .Collection ;
56import java .util .Deque ;
67import java .util .Map ;
8+ import java .util .function .BinaryOperator ;
9+ import java .util .stream .Stream ;
710
811/**
912 * Implements the algorithm described in Philip Wadler's "A prettier printer", a
@@ -151,6 +154,8 @@ public Doc indent(int indent) {
151154 * Bracket the current document by the {@code left} and {@code right} Strings,
152155 * indented by {@code indent} spaces.
153156 *
157+ * When collapsed, line separators are replaced by spaces.
158+ *
154159 * @param indent the number of spaces of indent to apply.
155160 * @param left the left-hand bracket String.
156161 * @param right the right-hand bracket String.
@@ -164,16 +169,50 @@ public Doc bracket(int indent, String left, String right) {
164169 * Bracket the current document by the {@code left} and {@code right} documents,
165170 * indented by {@code indent} spaces.
166171 *
172+ * When collapsed, line separators are replaced by spaces.
173+ *
167174 * @param indent the number of spaces of indent to apply.
168175 * @param left the left-hand bracket document.
169176 * @param right the right-hand bracket document.
170177 * @return the bracketed document.
171178 */
172179 public Doc bracket (int indent , Doc left , Doc right ) {
180+ return bracket (indent , Doc .lineOrSpace (), left , right );
181+ }
182+
183+ /**
184+ * Bracket the current document by the {@code left} and {@code right} Strings,
185+ * indented by {@code indent} spaces.
186+ *
187+ * When collapsed, line separators are replaced by the {@code lineDoc}.
188+ *
189+ * @param indent the number of spaces of indent to apply.
190+ * @param lineDoc the line separator document.
191+ * @param left the left-hand bracket document.
192+ * @param right the right-hand bracket document.
193+ * @return the bracketed document.
194+ */
195+ public Doc bracket (int indent , Doc lineDoc , String left , String right ) {
196+ return bracket (indent , lineDoc , Doc .text (left ), Doc .text (right ));
197+ }
198+
199+ /**
200+ * Bracket the current document by the {@code left} and {@code right} documents,
201+ * indented by {@code indent} spaces.
202+ *
203+ * When collapsed, line separators are replaced by the {@code lineDoc}.
204+ *
205+ * @param indent the number of spaces of indent to apply.
206+ * @param lineDoc the line separator document.
207+ * @param left the left-hand bracket document.
208+ * @param right the right-hand bracket document.
209+ * @return the bracketed document.
210+ */
211+ public Doc bracket (int indent , Doc lineDoc , Doc left , Doc right ) {
173212 return group (
174213 left
175- .append (lineOrSpace () .append (this ).indent (indent ))
176- .appendLineOrSpace ( right ));
214+ .append (lineDoc .append (this ).indent (indent ))
215+ .append ( lineDoc . append ( right ) ));
177216 }
178217
179218 /**
@@ -691,13 +730,67 @@ public static Doc lineOr(String altText) {
691730 return new LineOr (text (altText ));
692731 }
693732
733+ /**
734+ * Reduce a collection of documents using the binary operator {@code fn},
735+ * returning an empty document if the collection is empty.
736+ *
737+ * @param documents the collection of documents.
738+ * @param fn the binary operator for combining documents.
739+ * @return a document built by reducing the {@code documents} using the operator
740+ * {@code fn}.
741+ */
742+ public static Doc fold (Collection <Doc > documents , BinaryOperator <Doc > fn ) {
743+ return fold (documents .stream (), fn );
744+ }
745+
746+ /**
747+ * Reduce a stream of documents using the binary operator {@code fn}, returning
748+ * an empty document if the stream is empty.
749+ *
750+ * @param documents the stream of documents.
751+ * @param fn the binary operator for combining documents.
752+ * @return a document built by reducing the {@code documents} using the operator
753+ * {@code fn}.
754+ */
755+ public static Doc fold (Stream <Doc > documents , BinaryOperator <Doc > fn ) {
756+ return documents .reduce (fn ).orElse (Doc .empty ());
757+ }
758+
759+ /**
760+ * Intersperse a {@code separator} document in between the elements of a
761+ * collection of documents.
762+ *
763+ * @param separator the separator document.
764+ * @param documents the collection of documents.
765+ * @return a document containing the concatenation of {@code documents}
766+ * separated by the {@code separator}.
767+ */
768+ public static Doc intersperse (Doc separator , Collection <Doc > documents ) {
769+ return intersperse (separator , documents .stream ());
770+ }
771+
772+ /**
773+ * Intersperse a {@code separator} document in between the elements of a stream
774+ * of documents.
775+ *
776+ * @param separator the separator document.
777+ * @param documents the stream of documents.
778+ * @return a document containing the concatenation of {@code documents}
779+ * separated by the {@code separator}.
780+ */
781+ public static Doc intersperse (Doc separator , Stream <Doc > documents ) {
782+ return Doc .fold (documents , (left , right ) -> {
783+ return left .append (separator ).append (right );
784+ });
785+ }
786+
694787 /**
695788 * Creates a {@link com.opencastsoftware.prettier4j.Doc Doc} which represents a
696789 * group that can be flattened into a more compact layout.
697790 *
698791 * @param doc the document which is declared as a group which may be flattened.
699792 * @return a {@link com.opencastsoftware.prettier4j.Doc Doc} which represents a
700- * group that can be flattened into a more compact layout.
793+ * group that can be flattened into a more compact layout.
701794 */
702795 public static Doc group (Doc doc ) {
703796 return alternatives (doc .flatten (), doc );
0 commit comments