Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Partial changes as per review
HelpWriter naming chagnes
Changed scaling to boolean scalable
fixed weird license comment formatting.
  • Loading branch information
Claudenw committed Oct 12, 2024
commit 7efdf8025b66b88df53b94cfdd0652d3aa359632
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,19 @@ public void printHelp(final String cmdLineSyntax, final String header, final Ite
}

if (autoUsage) {
helpWriter.writePara(format("%s %s %s", syntaxPrefix, cmdLineSyntax, asSyntaxOptions(options)));
helpWriter.appendParagraph(format("%s %s %s", syntaxPrefix, cmdLineSyntax, asSyntaxOptions(options)));
} else {
helpWriter.writePara(format("%s %s", syntaxPrefix, cmdLineSyntax));
helpWriter.appendParagraph(format("%s %s", syntaxPrefix, cmdLineSyntax));
}

if (!Util.isEmpty(header)) {
helpWriter.writePara(header);
helpWriter.appendParagraph(header);
}

helpWriter.writeTable(getTableDefinition(options));
helpWriter.appendTable(getTableDefinition(options));

if (!Util.isEmpty(footer)) {
helpWriter.writePara(footer);
helpWriter.appendParagraph(footer);
}
}

Expand All @@ -208,7 +208,7 @@ public final void printOptions(final Iterable<Option> options) throws IOExceptio
* @throws IOException If the output could not be written to the {@link HelpWriter}
*/
public final void printOptions(final TableDefinition tableDefinition) throws IOException {
helpWriter.writeTable(tableDefinition);
helpWriter.appendTable(tableDefinition);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/apache/commons/cli/help/HelpFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,11 @@ private HelpFormatter(final Builder builder) {
public TableDefinition getTableDefinition(final Iterable<Option> options) {
// set up the base TextStyle for the columns configured for the Option opt and arg values..
TextStyle.Builder builder = new TextStyle.Builder().setAlignment(TextStyle.Alignment.LEFT)
.setIndent(DEFAULT_LEFT_PAD).setScaling(TextStyle.Scaling.UNSCALED);
.setIndent(DEFAULT_LEFT_PAD).setScalable(false);
List<TextStyle> styles = new ArrayList<>();
styles.add(builder.get());
// set up showSince column
builder.setScaling(TextStyle.Scaling.SCALED).setLeftPad(DEFAULT_COLUMN_SPACING);
builder.setScalable(true).setLeftPad(DEFAULT_COLUMN_SPACING);
if (showSince) {
builder.setAlignment(TextStyle.Alignment.CENTER);
styles.add(builder.get());
Expand Down
24 changes: 12 additions & 12 deletions src/main/java/org/apache/commons/cli/help/HelpWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,55 +21,55 @@ Licensed to the Apache Software Foundation (ASF) under one or more

/**
* The definition of a semantic scribe. The semantic scribe write string to output based on the semantic meaning
* of the type of string. e.g. a Paragraph -vs- a Heading.
* of the type of string. e.g. a Paragraph versus a Heading.
* <p>
* The representation of the semantics is dependant upon the format being output. For example the plain text
* output for a paragraph may print the text followed by two line breaks, while an XHTML output would print the
* text surrounded by &lt;p&gt; and &lt;/p&gt;
* text surrounded by &lt;p&gt; and &lt;/p&gt;.
* </p>
* @since 1.10.0
*/
public interface HelpWriter extends Appendable {

/**
* Write a title.
* Appends a title.
*
* @param title the title to write.
* @throws IOException on write failure
*/
void writeTitle(CharSequence title) throws IOException;
void appendTitle(CharSequence title) throws IOException;

/**
* Writes a paragraph.
* Appends a paragraph.
*
* @param paragraph the paragraph to write.
* @throws IOException on write failure
*/
void writePara(CharSequence paragraph) throws IOException;
void appendParagraph(CharSequence paragraph) throws IOException;

/**
* Writes a header.
* Appends a header.
*
* @param level the level of the header. This is equivalent to the "1", "2", or "3" in the HTML "h1", "h2", "h3" tags.
* @param text the text for the header
* @throws IOException on write failure
*/
void writeHeader(int level, CharSequence text) throws IOException;
void appendHeader(int level, CharSequence text) throws IOException;

/**
* Writes a list.
* Appends a list.
*
* @param ordered {@code true} if the list should be ordered.
* @param list the list to write.
* @throws IOException on write failure
*/
void writeList(boolean ordered, Collection<CharSequence> list) throws IOException;
void appendList(boolean ordered, Collection<CharSequence> list) throws IOException;

/**
* Writes a table.
* Appends a table.
*
* @param table the table definition to write.
* @throws IOException on write failure
*/
void writeTable(TableDefinition table) throws IOException;
void appendTable(TableDefinition table) throws IOException;
}
35 changes: 18 additions & 17 deletions src/main/java/org/apache/commons/cli/help/TextHelpWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ public class TextHelpWriter extends AbstractHelpWriter {
/** Number of space characters before a list continuation line */
public static final int DEFAULT_LIST_INDENT = 7;

/** A blank line in the output */
private static final String BLANK_LINE = "";

/** Defines the TextStyle for paragraph, and associated output formats. */
private final TextStyle.Builder styleBuilder;

Expand Down Expand Up @@ -126,27 +129,27 @@ private void printQueue(final Queue<String> queue) throws IOException {
}

@Override
public void writeTitle(final CharSequence title) throws IOException {
public void appendTitle(final CharSequence title) throws IOException {
if (!Util.isEmpty(title)) {
TextStyle style = styleBuilder.get();
Queue<String> queue = makeColumnQueue(title, style);
queue.add(Util.createPadding(style.getLeftPad()) + Util.filledString(Math.min(title.length(), style.getMaxWidth()), '#'));
queue.add("");
queue.add(BLANK_LINE);
printQueue(queue);
}
}

@Override
public void writePara(final CharSequence paragraph) throws IOException {
public void appendParagraph(final CharSequence paragraph) throws IOException {
if (!Util.isEmpty(paragraph)) {
Queue<String> queue = makeColumnQueue(paragraph, styleBuilder.get());
queue.add("");
queue.add(BLANK_LINE);
printQueue(queue);
}
}

@Override
public void writeHeader(final int level, final CharSequence text) throws IOException {
public void appendHeader(final int level, final CharSequence text) throws IOException {
if (!Util.isEmpty(text)) {
if (level < 1) {
throw new IllegalArgumentException("level must be at least 1");
Expand All @@ -156,19 +159,19 @@ public void writeHeader(final int level, final CharSequence text) throws IOExcep
TextStyle style = styleBuilder.get();
Queue<String> queue = makeColumnQueue(text, style);
queue.add(Util.createPadding(style.getLeftPad()) + Util.filledString(Math.min(text.length(), style.getMaxWidth()), fillChars[idx]));
queue.add("");
queue.add(BLANK_LINE);
printQueue(queue);
}
}

@Override
public void writeList(final boolean ordered, final Collection<CharSequence> list) throws IOException {
public void appendList(final boolean ordered, final Collection<CharSequence> list) throws IOException {
if (list != null && !list.isEmpty()) {
TextStyle.Builder builder = new TextStyle.Builder().setLeftPad(styleBuilder.getLeftPad()).setIndent(DEFAULT_LIST_INDENT);
int i = 1;
for (CharSequence line : list) {
String entry = ordered ? format(" %s. %s", i++, Util.defaultValue(line, "")) :
format(" * %s", Util.defaultValue(line, ""));
String entry = ordered ? format(" %s. %s", i++, Util.defaultValue(line, BLANK_LINE)) :
format(" * %s", Util.defaultValue(line, BLANK_LINE));
builder.setMaxWidth(Math.min(styleBuilder.getMaxWidth(), entry.length()));
printQueue(makeColumnQueue(entry, builder.get()));
}
Expand Down Expand Up @@ -248,7 +251,7 @@ protected TableDefinition adjustTableFormat(final TableDefinition table) {
int adjustedMaxWidth = styleBuilder.getMaxWidth();
for (TextStyle.Builder builder : styleBuilders) {
adjustedMaxWidth -= builder.getLeftPad();
if (builder.getScaling() == TextStyle.Scaling.SCALED) {
if (builder.isScalable()) {
calcWidth += builder.getMaxWidth();
} else {
adjustedMaxWidth -= builder.getMaxWidth();
Expand All @@ -260,7 +263,7 @@ protected TableDefinition adjustTableFormat(final TableDefinition table) {
double fraction = adjustedMaxWidth * 1.0 / calcWidth;
for (int i = 0; i < styleBuilders.size(); i++) {
TextStyle.Builder builder = styleBuilders.get(i);
if (builder.getScaling() == TextStyle.Scaling.SCALED) {
if (builder.isScalable()) {
// resize and remove the padding from the maxWidth calculation.
styleBuilders.set(i, resize(builder, fraction));
}
Expand All @@ -277,10 +280,10 @@ protected TableDefinition adjustTableFormat(final TableDefinition table) {
}

@Override
public void writeTable(final TableDefinition rawTable) throws IOException {
public void appendTable(final TableDefinition rawTable) throws IOException {
TableDefinition table = adjustTableFormat(rawTable);
// write the table
writePara(table.caption());
appendParagraph(table.caption());

List<TextStyle> headerStyles = new ArrayList<>();
for (TextStyle style : table.columnStyle()) {
Expand Down Expand Up @@ -350,15 +353,13 @@ protected Queue<String> makeColumnQueue(final CharSequence columnData, final Tex
String indent = Util.createPadding(style.getIndent());
Queue<String> result = new LinkedList<>();
int wrapPos = 0;
int nextPos = 0;
int nextPos;
int wrappedMaxWidth = style.getMaxWidth() - indent.length();
while (wrapPos < columnData.length()) {
int workingWidth = wrapPos == 0 ? style.getMaxWidth() : wrappedMaxWidth;
nextPos = Util.findWrapPos(columnData, workingWidth, wrapPos);
CharSequence working = columnData.subSequence(wrapPos, nextPos);
StringBuilder sb = new StringBuilder(lpad);
sb.append(style.pad(wrapPos > 0, working));
result.add(sb.toString());
result.add(lpad + style.pad(wrapPos > 0, working));
wrapPos = Util.findNonWhitespacePos(columnData, nextPos);
wrapPos = wrapPos == -1 ? nextPos : wrapPos;
}
Expand Down
49 changes: 23 additions & 26 deletions src/main/java/org/apache/commons/cli/help/TextStyle.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ Licensed to the Apache Software Foundation (ASF) under one or more
import org.apache.commons.cli.Util;

/**
* The definition for styling blocks of text. Most common usage is to style columns in a table, but may also be used to
* specify default stylings for a {@link HelpWriter}.
* The definition for styling recommendations blocks of text. Most common usage is to style columns in a table, but may also be used to
* specify default styling for a {@link HelpWriter}. HelpWriters are free to ignore the TextStyle recommendations
* particularly where they are not supported or contradict common usage.
* @since 1.10.0
*/
public final class TextStyle {
Expand All @@ -36,13 +37,6 @@ public enum Alignment {
CENTER,
/** right justify the text */
RIGHT }
/** Types scaling */
public enum Scaling {
/** do not scale */
UNSCALED,
/** text may be scaled */
SCALED
}

/** the alignment */
private final Alignment alignment;
Expand All @@ -51,7 +45,7 @@ public enum Scaling {
/** The size of the indent on the second and any subsequent lines of text */
private final int indent;
/** The scaling allowed for the block */
private final Scaling scaling;
private final boolean scalable;
/** The minimum size of the text */
private final int minWidth;
/** The maximum size of the text */
Expand All @@ -67,8 +61,8 @@ public static final class Builder implements Supplier<TextStyle> {
private int leftPad;
/** the subsequent line indentation */
private int indent;
/** the scaling */
private Scaling scaling;
/** the scalable flag. Identifies text blocks that can be made narrower or wider as needed by the HelpWriter. */
private boolean scalable;
/** the minimum width */
private int minWidth;
/** the maximum width */
Expand All @@ -86,7 +80,7 @@ public static final class Builder implements Supplier<TextStyle> {
*/
public Builder() {
alignment = Alignment.LEFT;
scaling = Scaling.SCALED;
scalable = true;
maxWidth = UNSET_MAX_WIDTH;
}

Expand All @@ -98,7 +92,7 @@ public Builder(final TextStyle style) {
this.alignment = style.alignment;
this.leftPad = style.leftPad;
this.indent = style.indent;
this.scaling = style.scaling;
this.scalable = style.scalable;
this.minWidth = style.minWidth;
this.maxWidth = style.maxWidth;
}
Expand Down Expand Up @@ -155,21 +149,23 @@ public int getIndent() {
}

/**
* Sets the scaling value.
* @param scaling the new scaling value.
* Specifies if the column can be made wider or to narrower width to fit constraints of the HelpWriter and
* formatting.
* @param scalable if {@code true} the text width can be adjusted.
* @return this.
*/
public Builder setScaling(final Scaling scaling) {
this.scaling = scaling;
public Builder setScalable(final boolean scalable) {
this.scalable = scalable;
return this;
}

/**
* Gets the currently specified scaling value.
* Specifies if the column can be made wider or to narrower width to fit constraints of the HelpWriter and
* formatting.
* @return The currently specified scaling value.
*/
public Scaling getScaling() {
return scaling;
public boolean isScalable() {
return scalable;
}

/**
Expand Down Expand Up @@ -222,7 +218,7 @@ private TextStyle(final Builder builder) {
this.alignment = builder.alignment;
this.leftPad = builder.leftPad;
this.indent = builder.indent;
this.scaling = builder.scaling;
this.scalable = builder.scalable;
this.minWidth = builder.minWidth;
this.maxWidth = builder.maxWidth;
}
Expand Down Expand Up @@ -252,11 +248,12 @@ public int getIndent() {
}

/**
* Gets the scaling value.
* Specifies if the column can be made wider or to narrower width to fit constraints of the HelpWriter and
* formatting.
* @return the scaling value.
*/
public Scaling getScaling() {
return scaling;
public boolean isScalable() {
return scalable;
}

/**
Expand All @@ -278,7 +275,7 @@ public int getMaxWidth() {
@Override
public String toString() {
return String.format("TextStyle{%s, l:%s, i:%s, %s, min:%s, max:%s}",
alignment, leftPad, indent, scaling, minWidth, maxWidth == UNSET_MAX_WIDTH ? "unset" : maxWidth);
alignment, leftPad, indent, scalable, minWidth, maxWidth == UNSET_MAX_WIDTH ? "unset" : maxWidth);
}

/**
Expand Down
30 changes: 14 additions & 16 deletions src/main/java/org/apache/commons/cli/help/package-info.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
Expand Down
Loading