1 package org.daisy.pipeline.braille.common;
2
3 import java.util.Collections;
4 import java.util.Locale;
5
6 import org.daisy.braille.css.SimpleInlineStyle;
7 import org.daisy.pipeline.braille.css.CSSStyledText;
8
9 /**
10 * Hyphenation means morphological breaking within <em>words</em>. However this class is
11 * not only responsible for providing hyphenation opportunities, but all soft wrap
12 * opportunities (including but not restricted to those defined by the Unicode line
13 * breaking rules [UAX14]).
14 */
15 public interface Hyphenator extends Transform {
16
17 /**
18 * Indicate all soft wrap opportunities by inserting soft hyphens and zero width
19 * spaces. Don't add new soft wrap opportunities to words that already have a soft
20 * hyphen or zero width space in them. Soft wrap opportunities at white space may also
21 * be omitted. Apart from the insertion of these special characters no other
22 * transformations are allowed. This means that non-standard hyphenation can not be
23 * supported through this interface.
24 */
25 public FullHyphenator asFullHyphenator() throws UnsupportedOperationException;
26
27 /**
28 * Break the input into lines of a preferred and maximal length. Transformations such
29 * as non-standard hyphenation are allowed.
30 *
31 * A {@link LineBreaker} is not required to do any special white space processing, but
32 * it may.
33 *
34 * If the {@link FullHyphenator} returned by {@link #asFullHyphenator()} throws a {@link
35 * NonStandardHyphenationException}, the {@link #asLineBreaker()} method must not throw a {@link
36 * UnsupportedOperationException}.
37 */
38 public LineBreaker asLineBreaker() throws UnsupportedOperationException;
39
40 /* ------------------ */
41 /* asFullHyphenator() */
42 /* ------------------ */
43
44 public interface FullHyphenator {
45
46 public Iterable<CSSStyledText> transform(Iterable<CSSStyledText> text) throws NonStandardHyphenationException;
47
48 /**
49 * This method is intended to be overridden with a more optimal implementation.
50 */
51 public default String transform(String text, SimpleInlineStyle style, Locale language)
52 throws NonStandardHyphenationException {
53 return transform(Collections.singleton(new CSSStyledText(text, style, language)))
54 .iterator().next().getText();
55 }
56 }
57
58 /* --------------- */
59 /* asLineBreaker() */
60 /* --------------- */
61
62 public interface LineBreaker {
63
64 public LineIterator transform(String input, Locale language);
65
66 }
67
68 /**
69 * Thrown by {@link FullHyphenator} if non-standard breaks are present.
70 */
71 @SuppressWarnings("serial")
72 public class NonStandardHyphenationException extends RuntimeException {
73
74 public NonStandardHyphenationException() {
75 super();
76 }
77
78 public NonStandardHyphenationException(Throwable cause) {
79 super(cause);
80 }
81 }
82
83 /* ------------ */
84 /* LineIterator */
85 /* ------------ */
86
87 public interface LineIterator {
88
89 /**
90 * Returns true if there is remaining text to make a new line of.
91 */
92 public boolean hasNext();
93
94 /**
95 * Get the next line of text, with a length as close as possible to, but not
96 * exceding `limit` characters, breaking a word if needed. The line does not
97 * include a possible hyphen character (see {@link lineHasHyphen()}). `limit` must
98 * be greater than 0. If `force` is true, may not return an empty string. If
99 * `allowHyphens` is false, breaking words is not permitted unless `force` is true
100 * and an empty string would otherwise be returned. Must throw an exception if
101 * there is no remaining text to make a new line of.
102 */
103 public String nextLine(int limit, boolean force, boolean allowHyphens);
104 public String nextLine(int limit, boolean force);
105
106 /**
107 * Whether or not a hyphen character should be inserted at the end of
108 * the current line to indicate a word break. Must throw an exception
109 * if `nextLine` hasn't been called yet.
110 */
111 public boolean lineHasHyphen();
112
113 public String remainder();
114
115 /**
116 * Set a checkpoint to which the iterator can be `reset` later.
117 */
118 public void mark();
119
120 /**
121 * Roll back to a checkpoint previously set with `mark`, or to the
122 * beginning if `mark` hasn't been called yet.
123 */
124 public void reset();
125
126 }
127 }