From 9225c9d31b34ba1edb979de4cba54edc210d08bd Mon Sep 17 00:00:00 2001
From: resaldiv <72623351+resaldiv@users.noreply.github.com>
Date: Tue, 20 Oct 2020 14:41:28 -0700
Subject: [PATCH 1/3] Add support to return a span element without a code wrap
---
__tests__/index.spec.tsx | 15 +++++++++++++++
src/index.ts | 9 ++++++---
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/__tests__/index.spec.tsx b/__tests__/index.spec.tsx
index c7aef42..16006d3 100644
--- a/__tests__/index.spec.tsx
+++ b/__tests__/index.spec.tsx
@@ -193,6 +193,21 @@ describe("Ansi", () => {
);
});
+ test("can spanify", () => {
+ const el = shallow(
+ React.createElement(
+ Ansi,
+ { spanify: true },
+ "spanify works"
+ )
+ );
+ expect(el).not.toBeNull();
+ expect(el.text()).toBe("spanify works");
+ expect(el.html()).toBe(
+ 'spanify works'
+ );
+ });
+
describe("useClasses options", () => {
test("can add the font color class", () => {
const el = shallow(
diff --git a/src/index.ts b/src/index.ts
index 888670a..e92b791 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -143,13 +143,16 @@ declare interface Props {
linkify?: boolean;
className?: string;
useClasses?: boolean;
+ spanify?: boolean;
}
export default function Ansi(props: Props): JSX.Element {
- const { className, useClasses, children, linkify } = props;
+ const { className, useClasses, children, linkify, spanify } = props;
+ const elementType = spanify ? React.Fragment : "code";
+ const elementProps = spanify ? null : { className };
return React.createElement(
- "code",
- { className },
+ elementType,
+ elementProps,
ansiToJSON(children ?? "", useClasses ?? false).map(
convertBundleIntoReact.bind(null, linkify ?? false, useClasses ?? false)
)
From fefe5ef3a4b404862de3cacc083e81dfa5c1d85b Mon Sep 17 00:00:00 2001
From: resaldiv <72623351+resaldiv@users.noreply.github.com>
Date: Thu, 22 Oct 2020 13:42:13 -0700
Subject: [PATCH 2/3] Change spanify prop to be as
---
__tests__/index.spec.tsx | 50 ++++++++++++++++++++++++++++------------
src/index.ts | 8 +++----
2 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/__tests__/index.spec.tsx b/__tests__/index.spec.tsx
index 16006d3..0d5c7e3 100644
--- a/__tests__/index.spec.tsx
+++ b/__tests__/index.spec.tsx
@@ -193,21 +193,6 @@ describe("Ansi", () => {
);
});
- test("can spanify", () => {
- const el = shallow(
- React.createElement(
- Ansi,
- { spanify: true },
- "spanify works"
- )
- );
- expect(el).not.toBeNull();
- expect(el.text()).toBe("spanify works");
- expect(el.html()).toBe(
- 'spanify works'
- );
- });
-
describe("useClasses options", () => {
test("can add the font color class", () => {
const el = shallow(
@@ -284,4 +269,39 @@ describe("Ansi", () => {
);
});
});
+
+ describe("as span", () => {
+ test("can return hello world as a span element", () => {
+ const el = shallow(
+ React.createElement(Ansi, { as: "span" }, "hello world")
+ );
+ expect(el).not.toBeNull();
+ expect(el.text()).toBe("hello world");
+ expect(el.html()).toBe(
+ 'hello world'
+ );
+ });
+
+ test("can return a link as a span element", () => {
+ const el = shallow(
+ React.createElement(Ansi, { as: "span", linkify: true }, "https://nteract.io/")
+ );
+ expect(el).not.toBeNull();
+ expect(el.text()).toBe("https://nteract.io/");
+ expect(el.html()).toBe(
+ 'https://nteract.io/'
+ );
+ });
+
+ test("can return nested span elements with color", () => {
+ const el = shallow(
+ React.createElement(Ansi, { as: "span" }, `${GREEN_FG}hello ${YELLOW_BG}world`)
+ );
+ expect(el).not.toBeNull();
+ expect(el.text()).toBe("hello world");
+ expect(el.html()).toBe(
+ 'hello world'
+ );
+ });
+ });
});
diff --git a/src/index.ts b/src/index.ts
index e92b791..764842f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -143,13 +143,13 @@ declare interface Props {
linkify?: boolean;
className?: string;
useClasses?: boolean;
- spanify?: boolean;
+ as?: string;
}
export default function Ansi(props: Props): JSX.Element {
- const { className, useClasses, children, linkify, spanify } = props;
- const elementType = spanify ? React.Fragment : "code";
- const elementProps = spanify ? null : { className };
+ const { className, useClasses, children, linkify, as } = props;
+ const elementType = ( as === "span" ) ? React.Fragment : "code";
+ const elementProps = ( as === "span" ) ? null : { className };
return React.createElement(
elementType,
elementProps,
From a0f6252d62866fc74fed42e36d67598eb9256e51 Mon Sep 17 00:00:00 2001
From: resaldiv <72623351+resaldiv@users.noreply.github.com>
Date: Wed, 28 Oct 2020 19:03:00 -0700
Subject: [PATCH 3/3] Add support to use anser as a prop
---
__tests__/index.spec.tsx | 46 ++++++++++++++++++++++++++++++++++++++++
src/index.ts | 10 +++++----
2 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/__tests__/index.spec.tsx b/__tests__/index.spec.tsx
index 0d5c7e3..9120e54 100644
--- a/__tests__/index.spec.tsx
+++ b/__tests__/index.spec.tsx
@@ -1,12 +1,14 @@
import { shallow } from "enzyme";
import React from "react";
+import Anser from "anser";
import Ansi from "../src/index";
const GREEN_FG = "\u001b[32m";
const YELLOW_BG = "\u001b[43m";
const BOLD = "\u001b[1m";
const RESET = "\u001b[0;m";
+const NO_OP = "\u001b[99m";
describe("Ansi", () => {
test("hello world", () => {
@@ -304,4 +306,48 @@ describe("Ansi", () => {
);
});
});
+
+ describe("data in chunks", () => {
+ describe("without anser prop", () => {
+ test("doesn't carry colors over", () => {
+ const dataInChunks = [`${GREEN_FG}hello `, `${YELLOW_BG}world`];
+ let el = "";
+ dataInChunks.map((spandata) =>
+ el += (shallow(React.createElement(Ansi, { as: "span" }, spandata)).html())
+ );
+ expect(el).not.toBeNull();
+ expect(el).toBe(
+ 'hello world'
+ );
+ });
+ });
+
+ describe("with anser prop", () => {
+ test("can carry colors over", () => {
+ const anser = new Anser();
+ const dataInChunks = [`${GREEN_FG}hello `, `${YELLOW_BG}world`];
+ let el = "";
+ dataInChunks.map((spandata) =>
+ el += (shallow(React.createElement(Ansi, { as: "span", anser: anser }, spandata)).html())
+ );
+ expect(el).not.toBeNull();
+ expect(el).toBe(
+ 'hello world'
+ );
+ });
+
+ test("can carry colors over using a no-op option for chunks without code", () => {
+ const anser = new Anser();
+ const dataInChunks = [`${GREEN_FG}hello `, `${NO_OP}world`];
+ let el = "";
+ dataInChunks.map((spandata) =>
+ el += (shallow(React.createElement(Ansi, { as: "span", anser: anser }, spandata)).html())
+ );
+ expect(el).not.toBeNull();
+ expect(el).toBe(
+ 'hello world'
+ );
+ });
+ });
+ });
});
diff --git a/src/index.ts b/src/index.ts
index 764842f..7b1bfe7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -13,10 +13,11 @@ import * as React from "react";
*/
function ansiToJSON(
input: string,
- use_classes: boolean = false
+ use_classes: boolean = false,
+ anser: Anser
): AnserJsonEntry[] {
input = escapeCarriageReturn(input);
- return Anser.ansiToJson(input, {
+ return anser.ansiToJson(input, {
json: true,
remove_empty: true,
use_classes
@@ -144,16 +145,17 @@ declare interface Props {
className?: string;
useClasses?: boolean;
as?: string;
+ anser?: Anser;
}
export default function Ansi(props: Props): JSX.Element {
- const { className, useClasses, children, linkify, as } = props;
+ const { className, useClasses, children, linkify, as, anser } = props;
const elementType = ( as === "span" ) ? React.Fragment : "code";
const elementProps = ( as === "span" ) ? null : { className };
return React.createElement(
elementType,
elementProps,
- ansiToJSON(children ?? "", useClasses ?? false).map(
+ ansiToJSON(children ?? "", useClasses ?? false, anser ?? new Anser()).map(
convertBundleIntoReact.bind(null, linkify ?? false, useClasses ?? false)
)
);