src/main/java/de/unixwork/uwproj/Feature.java

changeset 162
79eeb33c738f
parent 123
d89b75fdf0aa
child 165
f4f11f755ee7
equal deleted inserted replaced
161:3d1cd23f88f7 162:79eeb33c738f
4 4
5 import java.util.List; 5 import java.util.List;
6 6
7 import static de.unixwork.uwproj.Util.shId; 7 import static de.unixwork.uwproj.Util.shId;
8 8
9 public final class Feature { 9 public final class Feature extends AbstractOption {
10 private final String name; 10 private final String name;
11 private final String arg;
12 private final boolean auto; 11 private final boolean auto;
13 private final TargetData targetData; 12 private final TargetData targetData;
14 private final TargetData disabled = new TargetData(); 13 private final TargetData disabled = new TargetData();
15 private String desc = "";
16 14
17 public Feature(Element e) { 15 public Feature(Element e) {
16 super(Util.getAttrOrDefault(e, "arg", e.getAttribute("name")));
18 name = e.getAttribute("name"); 17 name = e.getAttribute("name");
19 arg = Util.getAttrOrDefault(e, "arg", name);
20 auto = Boolean.parseBoolean(e.getAttribute("default")); 18 auto = Boolean.parseBoolean(e.getAttribute("default"));
21 targetData = new TargetData(e); 19 targetData = new TargetData(e);
22 20
23 Util.getChildElements(e).forEach(elm -> { 21 Util.getChildElements(e).forEach(elm -> {
24 switch (elm.getNodeName()) { 22 switch (elm.getNodeName()) {
66 64
67 public boolean isAuto() { 65 public boolean isAuto() {
68 return auto; 66 return auto;
69 } 67 }
70 68
71 /** 69 @Override
72 * Generates help text for the feature option. 70 public String getHelpTextArg() {
73 * <p> 71 return (auto ? "--disable-" : "--enable-")+arg;
74 * If {@link #isAuto()} returns true, the option name will be --disable-${@link #getArg()}, otherwise
75 * it will be --enable-${@link #getArg()}, preceded by two spaces, respectively.
76 * <p>
77 * If no description is available via {@link #getDesc()}, only the option name is generated. Otherwise,
78 * description is added according to the following rules:
79 * <p>
80 * When the option name does not consume more than 25 characters, the description starts in the same line.
81 * Otherwise, a line break is added, first. The description will be placed in a block starting from column
82 * 27 to 80 and automatically break when necessary. The description must not contain a single word
83 * that is longer than 54 characters, or it will break the layout.
84 *
85 * @return a help text for terminal output
86 */
87 public String getHelpText() {
88 final var builder = new StringBuilder();
89
90 // Compute option name
91 final var opt = (auto ? " --disable-" : " --enable-")+arg;
92
93 // Add option name
94 builder.append(opt);
95
96 // Stop, if there is no description
97 if (desc.isBlank()) return builder.toString();
98
99 // Prepare the description by replacing some unwanted spaces
100 final var hdesc = desc.trim()
101 .replaceAll("\\r", "")
102 .replaceAll("\\t", " ");
103
104 // Declare our frame where the description shall be placed
105 final int startx = 26;
106 final int endx = 80;
107
108 // Move to startx (break, if we already past that)
109 if (opt.length() >= startx) {
110 builder.append("\n");
111 builder.append(" ".repeat(startx));
112 } else {
113 builder.append(" ".repeat(startx-opt.length()));
114 }
115
116 // Append the description keeping the layout intact
117 int x = startx;
118 for (int i = 0 ; i < hdesc.length() ;) {
119 // get the next word and see where we would end
120 int s = hdesc.indexOf(' ', i);
121 if (s < 0) s = hdesc.length();
122 int n = hdesc.indexOf('\n', i);
123 if (n < 0) n = hdesc.length();
124 s = Math.min(s, n);
125 int l = s-i;
126 if (x + l > endx) {
127 // does not fit, break into next line
128 builder.append('\n');
129 builder.append(" ".repeat(startx));
130 x = startx;
131 }
132 // append the word
133 builder.append(hdesc, i, s);
134 x += l;
135 i += l;
136 // append the next spaces
137 while (i < hdesc.length()) {
138 int c = hdesc.charAt(i);
139 if (c == ' ') {
140 // as long as we don't need to break, add the spaces
141 i++;
142 x++;
143 if (x < endx) builder.append(' ');
144 } else if (c == '\n') {
145 // if user wants us to break, comply
146 i++;
147 // if we have still space, just move to the end of the line
148 if (x < endx) {
149 x = endx;
150 } else {
151 // otherwise, we need to add an extra blank line
152 builder.append('\n');
153 }
154 } else {
155 // we have found the next word, so continue with the outer loop
156 break;
157 }
158 }
159 // break to new line, when spaces moved us outside the frame
160 if (x > endx) {
161 builder.append('\n');
162 builder.append(" ".repeat(startx));
163 x = startx;
164 }
165 }
166
167 return builder.toString();
168 } 72 }
169 } 73 }

mercurial