1 package be
.nikiroo
.utils
.main
;
3 import java
.util
.AbstractMap
;
4 import java
.util
.ArrayList
;
6 import java
.util
.Map
.Entry
;
7 import java
.util
.Scanner
;
9 import be
.nikiroo
.utils
.StringUtils
;
10 import be
.nikiroo
.utils
.StringUtils
.Alignment
;
13 * Text justification (left, right, center, justify).
17 public class justify
{
19 * Syntax: $0 ([left|right|center|justify]) (max width)
22 * <li>mode: left, right, center or full justification (defaults to left)</li>
23 * <li>max width: the maximum width of a line, or "" for "no maximum"
24 * (defaults to "no maximum")</li>
29 public static void main(String
[] args
) {
31 StringUtils
.Alignment align
= Alignment
.LEFT
;
33 if (args
.length
>= 1) {
34 align
= Alignment
.valueOf(args
[0].toUpperCase());
36 if (args
.length
>= 2) {
37 width
= Integer
.parseInt(args
[1]);
40 // TODO: move to utils?
41 // Content <-> Bullet spacing (null = no spacing)
42 List
<Entry
<String
, String
>> lines
= new ArrayList
<Entry
<String
, String
>>();
43 Scanner scan
= new Scanner(System
.in
);
44 scan
.useDelimiter("\r\n|[\r\n]");
46 StringBuilder previous
= null;
47 StringBuilder tmp
= new StringBuilder();
48 String previousItemBulletSpacing
= null;
49 String itemBulletSpacing
= null;
50 while (scan
.hasNext()) {
51 boolean previousLineComplete
= true;
53 String current
= scan
.next().replace("\t", " ");
54 itemBulletSpacing
= getItemSpacing(current
);
55 boolean bullet
= isItemLine(current
);
56 if ((previousItemBulletSpacing
== null || itemBulletSpacing
57 .length() <= previousItemBulletSpacing
.length())
59 itemBulletSpacing
= null;
62 if (itemBulletSpacing
!= null) {
63 current
= current
.trim();
64 if (!current
.isEmpty() && bullet
) {
65 current
= current
.substring(1);
67 current
= current
.trim();
68 previousLineComplete
= bullet
;
71 for (String word
: current
.split(" ")) {
76 if (tmp
.length() > 0) {
79 tmp
.append(word
.trim());
81 current
= tmp
.toString();
83 previousLineComplete
= current
.isEmpty()
84 || previousItemBulletSpacing
!= null
85 || (previous
!= null && isFullLine(previous
));
88 if (previous
== null) {
89 previous
= new StringBuilder();
91 if (previousLineComplete
) {
92 lines
.add(new AbstractMap
.SimpleEntry
<String
, String
>(
93 previous
.toString(), previousItemBulletSpacing
));
94 previous
.setLength(0);
95 previousItemBulletSpacing
= itemBulletSpacing
;
101 previous
.append(current
);
105 if (previous
!= null) {
106 lines
.add(new AbstractMap
.SimpleEntry
<String
, String
>(previous
107 .toString(), previousItemBulletSpacing
));
113 for (Entry
<String
, String
> line
: lines
) {
114 String content
= line
.getKey();
115 String spacing
= line
.getValue();
117 String bullet
= "- ";
118 if (spacing
== null) {
123 if (spacing
.length() > width
+ 3) {
127 for (String subline
: StringUtils
.justifyText(content
, width
128 - (spacing
.length() + bullet
.length()), align
)) {
129 System
.out
.println(spacing
+ bullet
+ subline
);
130 if (!bullet
.isEmpty()) {
137 static private boolean isFullLine(StringBuilder line
) {
138 return line
.length() == 0 //
139 || line
.charAt(line
.length() - 1) == '.'
140 || line
.charAt(line
.length() - 1) == '"'
141 || line
.charAt(line
.length() - 1) == 'ยป';
144 static private boolean isItemLine(String line
) {
145 String spacing
= getItemSpacing(line
);
146 return spacing
!= null && line
.charAt(spacing
.length()) == '-';
149 static private String
getItemSpacing(String line
) {
151 for (i
= 0; i
< line
.length(); i
++) {
152 if (line
.charAt(i
) != ' ') {
153 return line
.substring(0, i
);