This commit is contained in:
Looly 2022-04-27 13:49:31 +08:00
parent c2cdbb16f8
commit 8e797bd9c1
12 changed files with 2339 additions and 1880 deletions

File diff suppressed because it is too large Load Diff

1878
CHANGELOG_5.0-5.7.md Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
package cn.hutool.core.lang.ansi;
import cn.hutool.core.lang.Assert;
/**
* ANSI 8-bit前景或背景色即8位编码共256种颜色2^8 <br>
* <ul>
* <li>0-7 标准颜色同ESC [ 3037 m</li>
* <li>8-15 高强度颜色同ESC [ 9097 m</li>
* <li>16-2316 × 6 × 6 216色 16 + 36 × r + 6 × g + b (0 r, g, b 5)</li>
* <li>232-255 从黑到白的24阶灰度色</li>
* </ul>
*
* <p>来自Spring Boot</p>
*
* @author Toshiaki Maki, Phillip Webb
* @see #foreground(int)
* @see #background(int)
* @since 5.8.0
*/
public final class Ansi8BitColor implements AnsiElement {
private static final String PREFIX_FORE = "38;5;";
private static final String PREFIX_BACK = "48;5;";
/**
* 前景色ANSI颜色实例
*
* @param code 颜色代码(0-255)
* @return 前景色ANSI颜色实例
*/
public static Ansi8BitColor foreground(int code) {
return new Ansi8BitColor(PREFIX_FORE, code);
}
/**
* 背景色ANSI颜色实例
*
* @param code 颜色代码(0-255)
* @return 背景色ANSI颜色实例
*/
public static Ansi8BitColor background(int code) {
return new Ansi8BitColor(PREFIX_BACK, code);
}
private final String prefix;
private final int code;
/**
* 构造
*
* @param prefix 前缀
* @param code 颜色代码(0-255)
* @throws IllegalArgumentException 颜色代码不在0~255范围内
*/
private Ansi8BitColor(String prefix, int code) {
Assert.isTrue(code >= 0 && code <= 255, "Code must be between 0 and 255");
this.prefix = prefix;
this.code = code;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Ansi8BitColor other = (Ansi8BitColor) obj;
return this.prefix.equals(other.prefix) && this.code == other.code;
}
@Override
public int hashCode() {
return this.prefix.hashCode() * 31 + this.code;
}
@Override
public String toString() {
return this.prefix + this.code;
}
}

View File

@ -0,0 +1,109 @@
package cn.hutool.core.lang.ansi;
/**
* ANSI背景颜色枚举
*
* <p>来自Spring Boot</p>
*
* @author Phillip Webb, Geoffrey Chandler
* @since 5.8.0
*/
public enum AnsiBackground implements AnsiElement {
/**
* 默认背景色
*/
DEFAULT("49"),
/**
* 黑色
*/
BLACK("40"),
/**
*
*/
RED("41"),
/**
* 绿
*/
GREEN("42"),
/**
*
*/
YELLOW("43"),
/**
*
*/
BLUE("44"),
/**
* 品红
*/
MAGENTA("45"),
/**
*
*/
CYAN("46"),
/**
*
*/
WHITE("47"),
/**
* 亮黑
*/
BRIGHT_BLACK("100"),
/**
* 亮红
*/
BRIGHT_RED("101"),
/**
* 亮绿
*/
BRIGHT_GREEN("102"),
/**
* 亮黄
*/
BRIGHT_YELLOW("103"),
/**
* 亮蓝
*/
BRIGHT_BLUE("104"),
/**
* 亮品红
*/
BRIGHT_MAGENTA("105"),
/**
* 亮青
*/
BRIGHT_CYAN("106"),
/**
* 亮白
*/
BRIGHT_WHITE("107");
private final String code;
AnsiBackground(String code) {
this.code = code;
}
@Override
public String toString() {
return this.code;
}
}

View File

@ -0,0 +1,109 @@
package cn.hutool.core.lang.ansi;
/**
* ANSI标准颜色
*
* <p>来自Spring Boot</p>
*
* @author Phillip Webb, Geoffrey Chandler
* @since 5.8.0
*/
public enum AnsiColor implements AnsiElement {
/**
* 默认前景色
*/
DEFAULT("39"),
/**
*
*/
BLACK("30"),
/**
*
*/
RED("31"),
/**
* 绿
*/
GREEN("32"),
/**
*
*/
YELLOW("33"),
/**
*
*/
BLUE("34"),
/**
* 品红
*/
MAGENTA("35"),
/**
*
*/
CYAN("36"),
/**
*
*/
WHITE("37"),
/**
* 亮黑
*/
BRIGHT_BLACK("90"),
/**
* 亮红
*/
BRIGHT_RED("91"),
/**
* 亮绿
*/
BRIGHT_GREEN("92"),
/**
* 亮黄
*/
BRIGHT_YELLOW("93"),
/**
* 亮蓝
*/
BRIGHT_BLUE("94"),
/**
* 亮品红
*/
BRIGHT_MAGENTA("95"),
/**
* 亮青
*/
BRIGHT_CYAN("96"),
/**
* 亮白
*/
BRIGHT_WHITE("97");
private final String code;
AnsiColor(String code) {
this.code = code;
}
@Override
public String toString() {
return this.code;
}
}

View File

@ -0,0 +1,18 @@
package cn.hutool.core.lang.ansi;
/**
* ANSI可转义节点接口实现为ANSI颜色等
*
* <p>来自Spring Boot</p>
*
* @author Phillip Webb
*/
public interface AnsiElement {
/**
* @return ANSI转义编码
*/
@Override
String toString();
}

View File

@ -0,0 +1,65 @@
package cn.hutool.core.lang.ansi;
/**
* 生成ANSI格式的编码输出
*
* @author Phillip Webb
* @since 1.0.0
*/
public abstract class AnsiEncoder {
private static final String ENCODE_JOIN = ";";
private static final String ENCODE_START = "\033[";
private static final String ENCODE_END = "m";
private static final String RESET = "0;" + AnsiColor.DEFAULT;
/**
* 创建ANSI字符串参数中的{@link AnsiElement}会被转换为编码形式
*
* @param elements 节点数组
* @return ANSI字符串
*/
public static String encode(Object... elements) {
final StringBuilder sb = new StringBuilder();
buildEnabled(sb, elements);
return sb.toString();
}
/**
* 追加需要需转义的节点
*
* @param sb {@link StringBuilder}
* @param elements 节点列表
*/
private static void buildEnabled(StringBuilder sb, Object[] elements) {
boolean writingAnsi = false;
boolean containsEncoding = false;
for (Object element : elements) {
if (null == element) {
continue;
}
if (element instanceof AnsiElement) {
containsEncoding = true;
if (writingAnsi) {
sb.append(ENCODE_JOIN);
} else {
sb.append(ENCODE_START);
writingAnsi = true;
}
} else {
if (writingAnsi) {
sb.append(ENCODE_END);
writingAnsi = false;
}
}
sb.append(element);
}
// 恢复默认
if (containsEncoding) {
sb.append(writingAnsi ? ENCODE_JOIN : ENCODE_START);
sb.append(RESET);
sb.append(ENCODE_END);
}
}
}

View File

@ -0,0 +1,49 @@
package cn.hutool.core.lang.ansi;
/**
* ANSI文本样式风格枚举
*
* <p>来自Spring Boot</p>
*
* @author Phillip Webb
* @since 5.8.0
*/
public enum AnsiStyle implements AnsiElement {
/**
* 重置/正常
*/
NORMAL("0"),
/**
* 粗体或增加强度
*/
BOLD("1"),
/**
* 弱化降低强度
*/
FAINT("2"),
/**
* 斜体
*/
ITALIC("3"),
/**
* 下划线
*/
UNDERLINE("4");
private final String code;
AnsiStyle(String code) {
this.code = code;
}
@Override
public String toString() {
return this.code;
}
}

View File

@ -0,0 +1,6 @@
/**
* 命令行终端中ANSI 转义序列相关封装如ANSI颜色等
*
* @author spring, looly
*/
package cn.hutool.core.lang.ansi;

View File

@ -2541,7 +2541,7 @@ public class NumberUtil {
/**
* int值转byte数组使用大端字节序高位字节在前低位字节在后<br>
* http://www.ruanyifeng.com/blog/2016/11/byte-order.html
* <a href="http://www.ruanyifeng.com/blog/2016/11/byte-order.html">http://www.ruanyifeng.com/blog/2016/11/byte-order.html</a>
*
* @param value
* @return byte数组
@ -2560,7 +2560,7 @@ public class NumberUtil {
/**
* byte数组转int使用大端字节序高位字节在前低位字节在后<br>
* http://www.ruanyifeng.com/blog/2016/11/byte-order.html
* <a href="http://www.ruanyifeng.com/blog/2016/11/byte-order.html">http://www.ruanyifeng.com/blog/2016/11/byte-order.html</a>
*
* @param bytes byte数组
* @return int

View File

@ -75,4 +75,9 @@ public class ConsoleTest {
}
}
@Test
public void printColorTest(){
System.out.print("\33[30;1m A \u001b[31;2m B \u001b[32;1m C \u001b[33;1m D \u001b[0m");
}
}

View File

@ -0,0 +1,13 @@
package cn.hutool.core.lang.ansi;
import org.junit.Assert;
import org.junit.Test;
public class AnsiEncoderTest {
@Test
public void encodeTest(){
final String encode = AnsiEncoder.encode(AnsiColor.GREEN, "Hutool test");
Assert.assertEquals("\u001B[32mHutool test\u001B[0;39m", encode);
}
}