Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4c48ff630 |
2 changed files with 444 additions and 1 deletions
436
0001-Bring-back-the-AnsiRenderer-fixes-184.patch
Normal file
436
0001-Bring-back-the-AnsiRenderer-fixes-184.patch
Normal file
|
|
@ -0,0 +1,436 @@
|
|||
From faf93318be3cda0b3a3894ae9d2032835601bc73 Mon Sep 17 00:00:00 2001
|
||||
From: Guillaume Nodet <gnodet@gmail.com>
|
||||
Date: Wed, 20 Jan 2021 12:08:59 +0100
|
||||
Subject: [PATCH] Bring back the AnsiRenderer, fixes #184
|
||||
|
||||
---
|
||||
src/main/java/org/fusesource/jansi/Ansi.java | 27 ++
|
||||
.../org/fusesource/jansi/AnsiRenderer.java | 253 ++++++++++++++++++
|
||||
.../fusesource/jansi/AnsiRendererTest.java | 115 ++++++++
|
||||
3 files changed, 395 insertions(+)
|
||||
create mode 100644 src/main/java/org/fusesource/jansi/AnsiRenderer.java
|
||||
create mode 100644 src/test/java/org/fusesource/jansi/AnsiRendererTest.java
|
||||
|
||||
diff --git a/src/main/java/org/fusesource/jansi/Ansi.java b/src/main/java/org/fusesource/jansi/Ansi.java
|
||||
index 84976e0..a882705 100644
|
||||
--- a/src/main/java/org/fusesource/jansi/Ansi.java
|
||||
+++ b/src/main/java/org/fusesource/jansi/Ansi.java
|
||||
@@ -818,6 +818,33 @@ public class Ansi implements Appendable {
|
||||
return this;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Uses the {@link AnsiRenderer}
|
||||
+ * to generate the ANSI escape sequences for the supplied text.
|
||||
+ *
|
||||
+ * @param text text
|
||||
+ * @return this
|
||||
+ * @since 2.2
|
||||
+ */
|
||||
+ public Ansi render(final String text) {
|
||||
+ a(AnsiRenderer.render(text));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * String formats and renders the supplied arguments. Uses the {@link AnsiRenderer}
|
||||
+ * to generate the ANSI escape sequences.
|
||||
+ *
|
||||
+ * @param text format
|
||||
+ * @param args arguments
|
||||
+ * @return this
|
||||
+ * @since 2.2
|
||||
+ */
|
||||
+ public Ansi render(final String text, Object... args) {
|
||||
+ a(String.format(AnsiRenderer.render(text), args));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public String toString() {
|
||||
flushAttributes();
|
||||
diff --git a/src/main/java/org/fusesource/jansi/AnsiRenderer.java b/src/main/java/org/fusesource/jansi/AnsiRenderer.java
|
||||
new file mode 100644
|
||||
index 0000000..7565ae4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/fusesource/jansi/AnsiRenderer.java
|
||||
@@ -0,0 +1,253 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2009-2021 the original author(s).
|
||||
+ *
|
||||
+ * Licensed 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.
|
||||
+ */
|
||||
+package org.fusesource.jansi;
|
||||
+
|
||||
+import java.io.IOException;
|
||||
+import java.util.Locale;
|
||||
+
|
||||
+import org.fusesource.jansi.Ansi.Attribute;
|
||||
+import org.fusesource.jansi.Ansi.Color;
|
||||
+
|
||||
+/**
|
||||
+ * Renders ANSI color escape-codes in strings by parsing out some special syntax to pick up the correct fluff to use.
|
||||
+ *
|
||||
+ * The syntax for embedded ANSI codes is:
|
||||
+ *
|
||||
+ * <pre>
|
||||
+ * @|<em>code</em>(,<em>code</em>)* <em>text</em>|@
|
||||
+ * </pre>
|
||||
+ *
|
||||
+ * Examples:
|
||||
+ *
|
||||
+ * <pre>
|
||||
+ * @|bold Hello|@
|
||||
+ * </pre>
|
||||
+ *
|
||||
+ * <pre>
|
||||
+ * @|bold,red Warning!|@
|
||||
+ * </pre>
|
||||
+ *
|
||||
+ * @since 2.2
|
||||
+ */
|
||||
+public class AnsiRenderer {
|
||||
+
|
||||
+ public static final String BEGIN_TOKEN = "@|";
|
||||
+
|
||||
+ public static final String END_TOKEN = "|@";
|
||||
+
|
||||
+ public static final String CODE_TEXT_SEPARATOR = " ";
|
||||
+
|
||||
+ public static final String CODE_LIST_SEPARATOR = ",";
|
||||
+
|
||||
+ private static final int BEGIN_TOKEN_LEN = 2;
|
||||
+
|
||||
+ private static final int END_TOKEN_LEN = 2;
|
||||
+
|
||||
+ public static String render(final String input) throws IllegalArgumentException {
|
||||
+ try {
|
||||
+ return render(input, new StringBuilder()).toString();
|
||||
+ } catch (IOException e) {
|
||||
+ // Cannot happen because StringBuilder does not throw IOException
|
||||
+ throw new IllegalArgumentException(e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Renders the given input to the target Appendable.
|
||||
+ *
|
||||
+ * @param input
|
||||
+ * source to render
|
||||
+ * @param target
|
||||
+ * render onto this target Appendable.
|
||||
+ * @return the given Appendable
|
||||
+ * @throws IOException
|
||||
+ * If an I/O error occurs
|
||||
+ */
|
||||
+ public static Appendable render(final String input, Appendable target) throws IOException {
|
||||
+
|
||||
+ int i = 0;
|
||||
+ int j, k;
|
||||
+
|
||||
+ while (true) {
|
||||
+ j = input.indexOf(BEGIN_TOKEN, i);
|
||||
+ if (j == -1) {
|
||||
+ if (i == 0) {
|
||||
+ target.append(input);
|
||||
+ return target;
|
||||
+ }
|
||||
+ target.append(input.substring(i));
|
||||
+ return target;
|
||||
+ }
|
||||
+ target.append(input.substring(i, j));
|
||||
+ k = input.indexOf(END_TOKEN, j);
|
||||
+
|
||||
+ if (k == -1) {
|
||||
+ target.append(input);
|
||||
+ return target;
|
||||
+ }
|
||||
+ j += BEGIN_TOKEN_LEN;
|
||||
+ String spec = input.substring(j, k);
|
||||
+
|
||||
+ String[] items = spec.split(CODE_TEXT_SEPARATOR, 2);
|
||||
+ if (items.length == 1) {
|
||||
+ target.append(input);
|
||||
+ return target;
|
||||
+ }
|
||||
+ String replacement = render(items[1], items[0].split(CODE_LIST_SEPARATOR));
|
||||
+
|
||||
+ target.append(replacement);
|
||||
+
|
||||
+ i = k + END_TOKEN_LEN;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static String render(final String text, final String... codes) {
|
||||
+ return render(Ansi.ansi(), codes)
|
||||
+ .a(text).reset().toString();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Renders {@link Code} names as an ANSI escape string.
|
||||
+ * @param codes The code names to render
|
||||
+ * @return an ANSI escape string.
|
||||
+ */
|
||||
+ public static String renderCodes(final String... codes) {
|
||||
+ return render(Ansi.ansi(), codes).toString();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Renders {@link Code} names as an ANSI escape string.
|
||||
+ * @param codes A space separated list of code names to render
|
||||
+ * @return an ANSI escape string.
|
||||
+ */
|
||||
+ public static String renderCodes(final String codes) {
|
||||
+ return renderCodes(codes.split("\\s"));
|
||||
+ }
|
||||
+
|
||||
+ private static Ansi render(Ansi ansi, String... names) {
|
||||
+ for (String name : names) {
|
||||
+ Code code = Code.valueOf(name.toUpperCase(Locale.ENGLISH));
|
||||
+ if (code.isColor()) {
|
||||
+ if (code.isBackground()) {
|
||||
+ ansi.bg(code.getColor());
|
||||
+ } else {
|
||||
+ ansi.fg(code.getColor());
|
||||
+ }
|
||||
+ } else if (code.isAttribute()) {
|
||||
+ ansi.a(code.getAttribute());
|
||||
+ }
|
||||
+ }
|
||||
+ return ansi;
|
||||
+ }
|
||||
+
|
||||
+ public static boolean test(final String text) {
|
||||
+ return text != null && text.contains(BEGIN_TOKEN);
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unused")
|
||||
+ public enum Code {
|
||||
+ //
|
||||
+ // TODO: Find a better way to keep Code in sync with Color/Attribute/Erase
|
||||
+ //
|
||||
+
|
||||
+ // Colors
|
||||
+ BLACK(Color.BLACK),
|
||||
+ RED(Color.RED),
|
||||
+ GREEN(Color.GREEN),
|
||||
+ YELLOW(Color.YELLOW),
|
||||
+ BLUE(Color.BLUE),
|
||||
+ MAGENTA(Color.MAGENTA),
|
||||
+ CYAN(Color.CYAN),
|
||||
+ WHITE(Color.WHITE),
|
||||
+
|
||||
+ // Foreground Colors
|
||||
+ FG_BLACK(Color.BLACK, false),
|
||||
+ FG_RED(Color.RED, false),
|
||||
+ FG_GREEN(Color.GREEN, false),
|
||||
+ FG_YELLOW(Color.YELLOW, false),
|
||||
+ FG_BLUE(Color.BLUE, false),
|
||||
+ FG_MAGENTA(Color.MAGENTA, false),
|
||||
+ FG_CYAN(Color.CYAN, false),
|
||||
+ FG_WHITE(Color.WHITE, false),
|
||||
+
|
||||
+ // Background Colors
|
||||
+ BG_BLACK(Color.BLACK, true),
|
||||
+ BG_RED(Color.RED, true),
|
||||
+ BG_GREEN(Color.GREEN, true),
|
||||
+ BG_YELLOW(Color.YELLOW, true),
|
||||
+ BG_BLUE(Color.BLUE, true),
|
||||
+ BG_MAGENTA(Color.MAGENTA, true),
|
||||
+ BG_CYAN(Color.CYAN, true),
|
||||
+ BG_WHITE(Color.WHITE, true),
|
||||
+
|
||||
+ // Attributes
|
||||
+ RESET(Attribute.RESET),
|
||||
+ INTENSITY_BOLD(Attribute.INTENSITY_BOLD),
|
||||
+ INTENSITY_FAINT(Attribute.INTENSITY_FAINT),
|
||||
+ ITALIC(Attribute.ITALIC),
|
||||
+ UNDERLINE(Attribute.UNDERLINE),
|
||||
+ BLINK_SLOW(Attribute.BLINK_SLOW),
|
||||
+ BLINK_FAST(Attribute.BLINK_FAST),
|
||||
+ BLINK_OFF(Attribute.BLINK_OFF),
|
||||
+ NEGATIVE_ON(Attribute.NEGATIVE_ON),
|
||||
+ NEGATIVE_OFF(Attribute.NEGATIVE_OFF),
|
||||
+ CONCEAL_ON(Attribute.CONCEAL_ON),
|
||||
+ CONCEAL_OFF(Attribute.CONCEAL_OFF),
|
||||
+ UNDERLINE_DOUBLE(Attribute.UNDERLINE_DOUBLE),
|
||||
+ UNDERLINE_OFF(Attribute.UNDERLINE_OFF),
|
||||
+
|
||||
+ // Aliases
|
||||
+ BOLD(Attribute.INTENSITY_BOLD),
|
||||
+ FAINT(Attribute.INTENSITY_FAINT),;
|
||||
+
|
||||
+ private final Enum<?> n;
|
||||
+
|
||||
+ private final boolean background;
|
||||
+
|
||||
+ Code(final Enum<?> n, boolean background) {
|
||||
+ this.n = n;
|
||||
+ this.background = background;
|
||||
+ }
|
||||
+
|
||||
+ Code(final Enum<?> n) {
|
||||
+ this(n, false);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isColor() {
|
||||
+ return n instanceof Ansi.Color;
|
||||
+ }
|
||||
+
|
||||
+ public Ansi.Color getColor() {
|
||||
+ return (Ansi.Color) n;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isAttribute() {
|
||||
+ return n instanceof Attribute;
|
||||
+ }
|
||||
+
|
||||
+ public Attribute getAttribute() {
|
||||
+ return (Attribute) n;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isBackground() {
|
||||
+ return background;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private AnsiRenderer() {
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/test/java/org/fusesource/jansi/AnsiRendererTest.java b/src/test/java/org/fusesource/jansi/AnsiRendererTest.java
|
||||
new file mode 100644
|
||||
index 0000000..590a96b
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/org/fusesource/jansi/AnsiRendererTest.java
|
||||
@@ -0,0 +1,115 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2009-2021 the original author(s).
|
||||
+ *
|
||||
+ * Licensed 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.
|
||||
+ */
|
||||
+package org.fusesource.jansi;
|
||||
+
|
||||
+import org.junit.jupiter.api.BeforeAll;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.fusesource.jansi.Ansi.*;
|
||||
+import static org.fusesource.jansi.Ansi.Attribute.*;
|
||||
+import static org.fusesource.jansi.Ansi.Color.*;
|
||||
+import static org.fusesource.jansi.AnsiRenderer.*;
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+
|
||||
+/**
|
||||
+ * Tests for the {@link AnsiRenderer} class.
|
||||
+ *
|
||||
+ * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
|
||||
+ */
|
||||
+public class AnsiRendererTest {
|
||||
+
|
||||
+ @BeforeAll
|
||||
+ static void setUp() {
|
||||
+ Ansi.setEnabled(true);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testTest() throws Exception {
|
||||
+ assertFalse(test("foo"));
|
||||
+ assertTrue(test("@|foo|"));
|
||||
+ assertTrue(test("@|foo"));
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRender() {
|
||||
+ String str = render("@|bold foo|@");
|
||||
+ System.out.println(str);
|
||||
+ assertEquals(ansi().a(INTENSITY_BOLD).a("foo").reset().toString(), str);
|
||||
+ assertEquals(ansi().bold().a("foo").reset().toString(), str);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRenderCodes() {
|
||||
+ String str = renderCodes("bold red");
|
||||
+ System.out.println(str);
|
||||
+ assertEquals(ansi().bold().fg(Color.RED).toString(), str);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRender2() {
|
||||
+ String str = render("@|bold,red foo|@");
|
||||
+ System.out.println(str);
|
||||
+ assertEquals(Ansi.ansi().a(INTENSITY_BOLD).fg(RED).a("foo").reset().toString(), str);
|
||||
+ assertEquals(Ansi.ansi().bold().fgRed().a("foo").reset().toString(), str);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRender3() {
|
||||
+ String str = render("@|bold,red foo bar baz|@");
|
||||
+ System.out.println(str);
|
||||
+ assertEquals(ansi().a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset().toString(), str);
|
||||
+ assertEquals(ansi().bold().fgRed().a("foo bar baz").reset().toString(), str);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRender4() {
|
||||
+ String str = render("@|bold,red foo bar baz|@ ick @|bold,red foo bar baz|@");
|
||||
+ System.out.println(str);
|
||||
+ assertEquals(ansi()
|
||||
+ .a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset()
|
||||
+ .a(" ick ")
|
||||
+ .a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset()
|
||||
+ .toString(), str);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRender5() {
|
||||
+ // Check the ansi() render method.
|
||||
+ String str = ansi().render("@|bold Hello|@").toString();
|
||||
+ System.out.println(str);
|
||||
+ assertEquals(ansi().a(INTENSITY_BOLD).a("Hello").reset().toString(), str);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRenderNothing() {
|
||||
+ assertEquals("foo", render("foo"));
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRenderInvalidMissingEnd() {
|
||||
+ String str = render("@|bold foo");
|
||||
+ assertEquals("@|bold foo", str);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testRenderInvalidMissingText() {
|
||||
+ String str = render("@|bold|@");
|
||||
+ assertEquals("@|bold|@", str);
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.33.1
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
Name: jansi
|
||||
Version: 2.1.1
|
||||
Release: 3%{?dist}
|
||||
Release: 4%{?dist}
|
||||
Summary: Generate and interpret ANSI escape sequences in Java
|
||||
|
||||
License: ASL 2.0
|
||||
|
|
@ -8,6 +8,10 @@ URL: http://fusesource.github.io/jansi/
|
|||
Source0: https://github.com/fusesource/jansi/archive/jansi-%{version}.tar.gz
|
||||
# Change the location of the native artifact to where Fedora wants it
|
||||
Patch0: %{name}-jni.patch
|
||||
# Bring back AnsiRenderer
|
||||
# https://github.com/fusesource/jansi/commit/faf9331
|
||||
# Needed to build newer log4j
|
||||
Patch1: 0001-Bring-back-the-AnsiRenderer-fixes-184.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: maven-local
|
||||
|
|
@ -92,6 +96,9 @@ cp -p src/main/native/libjansi.so %{buildroot}%{_libdir}/%{name}
|
|||
%license license.txt
|
||||
|
||||
%changelog
|
||||
* Mon Dec 13 2021 Adam Williamson <awilliam@redhat.com> - 2.1.1-4
|
||||
- Backport patch to bring back AnsiRenderer
|
||||
|
||||
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.1-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue