Provide access to ansi values suitable for shell scripts

Required for https://github.com/dart-lang/mono_repo/issues/43
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c2565ea..5a26062 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 0.3.2
+
+* `ansi.dart`
+
+  * Added `forScript` named argument to top-level `wrapWith` function.
+
+  * `AnsiCode`
+
+    * Added `String get escapeForScript` property.
+
+    * Added `forScript` named argument to `wrap` function.
+
 ## 0.3.1
 
 - Added `SharedStdIn.nextLine` (similar to `readLineSync`) and `lines`:
diff --git a/example/ansi_code_example.dart b/example/ansi_code_example.dart
index 255bd72..e622f03 100644
--- a/example/ansi_code_example.dart
+++ b/example/ansi_code_example.dart
@@ -7,17 +7,19 @@
 import 'package:io/ansi.dart';
 
 /// Prints a sample of all of the `AnsiCode` values.
-void main() {
+void main(List<String> args) {
+  final forScript = args.contains('--for-script');
+
   if (!ansiOutputEnabled) {
     print('`ansiOutputEnabled` is `false`.');
     print("Don't expect pretty output.");
   }
-  _preview('Foreground', foregroundColors);
-  _preview('Background', backgroundColors);
-  _preview('Styles', styles);
+  _preview('Foreground', foregroundColors, forScript);
+  _preview('Background', backgroundColors, forScript);
+  _preview('Styles', styles, forScript);
 }
 
-void _preview(String name, List<AnsiCode> values) {
+void _preview(String name, List<AnsiCode> values, bool forScript) {
   print('');
   final longest = values.map((ac) => ac.name.length).reduce(max);
 
@@ -26,6 +28,6 @@
     final header =
         "${code.name.padRight(longest)} ${code.code.toString().padLeft(3)}";
 
-    print("$header: ${code.wrap('Sample')}");
+    print("$header: ${code.wrap('Sample', forScript: forScript)}");
   }
 }
diff --git a/lib/src/ansi_code.dart b/lib/src/ansi_code.dart
index beee945..87551ee 100644
--- a/lib/src/ansi_code.dart
+++ b/lib/src/ansi_code.dart
@@ -5,6 +5,9 @@
 import 'dart:async';
 import 'dart:io' as io;
 
+const _ansiEscapeLiteral = '\x1B';
+const _ansiEscapeForScript = '\\033';
+
 /// Whether formatted ANSI output is enabled for [wrapWith] and [AnsiCode.wrap].
 ///
 /// By default, returns `true` if both `stdout.supportsAnsiEscapes` and
@@ -66,20 +69,31 @@
   const AnsiCode._(this.name, this.type, this.code, this.reset);
 
   /// Represents the value escaped for use in terminal output.
-  String get escape => "\x1B[${code}m";
+  String get escape => "$_ansiEscapeLiteral[${code}m";
+
+  /// Represents the value as an unescaped literal suitable for scripts.
+  String get escapeForScript => "$_ansiEscapeForScript[${code}m";
+
+  String _escapeValue({bool forScript: false}) {
+    forScript ??= false;
+    return forScript ? escapeForScript : escape;
+  }
 
   /// Wraps [value] with the [escape] value for this code, followed by
   /// [resetAll].
   ///
+  /// If [forScript] is `true`, the return value is an unescaped literal.
+  ///
   /// Returns `value` unchanged if
   ///   * [value] is `null` or empty
   ///   * [ansiOutputEnabled] is `false`
   ///   * [type] is [AnsiCodeType.reset]
-  String wrap(String value) => (ansiOutputEnabled &&
+  String wrap(String value, {bool forScript: false}) => (ansiOutputEnabled &&
           type != AnsiCodeType.reset &&
           value != null &&
           value.isNotEmpty)
-      ? "$escape$value${reset.escape}"
+      ? "${_escapeValue(forScript: forScript)}$value"
+          "${reset._escapeValue(forScript: forScript)}"
       : value;
 
   @override
@@ -88,6 +102,8 @@
 
 /// Returns a [String] formatted with [codes].
 ///
+/// If [forScript] is `true`, the return value is an unescaped literal.
+///
 /// Returns `value` unchanged if
 ///   * [value] is `null` or empty.
 ///   * [ansiOutputEnabled] is `false`.
@@ -97,7 +113,9 @@
 ///   * [codes] contains more than one value of type [AnsiCodeType.foreground].
 ///   * [codes] contains more than one value of type [AnsiCodeType.background].
 ///   * [codes] contains any value of type [AnsiCodeType.reset].
-String wrapWith(String value, Iterable<AnsiCode> codes) {
+String wrapWith(String value, Iterable<AnsiCode> codes,
+    {bool forScript: false}) {
+  forScript ??= false;
   // Eliminate duplicates
   final myCodes = codes.toSet();
 
@@ -130,8 +148,10 @@
   }
 
   final sortedCodes = myCodes.map((ac) => ac.code).toList()..sort();
+  final escapeValue = forScript ? _ansiEscapeForScript : _ansiEscapeLiteral;
 
-  return "\x1B[${sortedCodes.join(';')}m$value${resetAll.escape}";
+  return "$escapeValue[${sortedCodes.join(';')}m$value"
+      "${resetAll._escapeValue(forScript: forScript)}";
 }
 
 //
diff --git a/pubspec.yaml b/pubspec.yaml
index 78ac7de..36a714d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
 name: io
 description: >
   Utilities for the Dart VM Runtime.
-version: 0.3.1
+version: 0.3.2
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/io
 
diff --git a/test/ansi_code_test.dart b/test/ansi_code_test.dart
index 89b2512..5c6805a 100644
--- a/test/ansi_code_test.dart
+++ b/test/ansi_code_test.dart
@@ -7,6 +7,9 @@
 import 'package:io/ansi.dart';
 import 'package:test/test.dart';
 
+const _ansiEscapeLiteral = '\x1B';
+const _ansiEscapeForScript = '\\033';
+
 void main() {
   group('ansiOutputEnabled', () {
     test("default value matches dart:io", () {
@@ -63,84 +66,106 @@
 
   final sampleInput = 'sample input';
 
-  group('wrap', () {
-    _test("color", () {
-      final expected = '\x1B[34m$sampleInput\x1B[0m';
+  for (var forScript in [true, false]) {
+    group(forScript ? 'for script' : 'literal', () {
+      final escapeLiteral =
+          forScript ? _ansiEscapeForScript : _ansiEscapeLiteral;
 
-      expect(blue.wrap(sampleInput), expected);
+      group('wrap', () {
+        _test("color", () {
+          final expected = '$escapeLiteral[34m$sampleInput$escapeLiteral[0m';
+
+          expect(blue.wrap(sampleInput, forScript: forScript), expected);
+        });
+
+        _test("style", () {
+          final expected = '$escapeLiteral[1m$sampleInput$escapeLiteral[22m';
+
+          expect(styleBold.wrap(sampleInput, forScript: forScript), expected);
+        });
+
+        _test("style", () {
+          final expected = '$escapeLiteral[34m$sampleInput$escapeLiteral[0m';
+
+          expect(blue.wrap(sampleInput, forScript: forScript), expected);
+        });
+
+        test("empty", () {
+          expect(blue.wrap('', forScript: forScript), '');
+        });
+
+        test(null, () {
+          expect(blue.wrap(null, forScript: forScript), isNull);
+        });
+      });
+
+      group('wrapWith', () {
+        _test("foreground", () {
+          final expected = '$escapeLiteral[34m$sampleInput$escapeLiteral[0m';
+
+          expect(wrapWith(sampleInput, [blue], forScript: forScript), expected);
+        });
+
+        _test("background", () {
+          final expected = '$escapeLiteral[44m$sampleInput$escapeLiteral[0m';
+
+          expect(wrapWith(sampleInput, [backgroundBlue], forScript: forScript),
+              expected);
+        });
+
+        _test("style", () {
+          final expected = '$escapeLiteral[1m$sampleInput$escapeLiteral[0m';
+
+          expect(wrapWith(sampleInput, [styleBold], forScript: forScript),
+              expected);
+        });
+
+        _test("2 styles", () {
+          final expected = '$escapeLiteral[1;3m$sampleInput$escapeLiteral[0m';
+
+          expect(
+              wrapWith(sampleInput, [styleBold, styleItalic],
+                  forScript: forScript),
+              expected);
+        });
+
+        _test("2 foregrounds", () {
+          expect(
+              () => wrapWith(sampleInput, [blue, white], forScript: forScript),
+              throwsArgumentError);
+        });
+
+        _test("multi", () {
+          final expected =
+              '$escapeLiteral[1;4;34;107m$sampleInput$escapeLiteral[0m';
+
+          expect(
+              wrapWith(sampleInput,
+                  [blue, backgroundWhite, styleBold, styleUnderlined],
+                  forScript: forScript),
+              expected);
+        });
+
+        test('no codes', () {
+          expect(wrapWith(sampleInput, []), sampleInput);
+        });
+
+        _test("empty", () {
+          expect(
+              wrapWith('', [blue, backgroundWhite, styleBold],
+                  forScript: forScript),
+              '');
+        });
+
+        _test(null, () {
+          expect(
+              wrapWith(null, [blue, backgroundWhite, styleBold],
+                  forScript: forScript),
+              isNull);
+        });
+      });
     });
-
-    _test("style", () {
-      final expected = '\x1B[1m$sampleInput\x1B[22m';
-
-      expect(styleBold.wrap(sampleInput), expected);
-    });
-
-    _test("style", () {
-      final expected = '\x1B[34m$sampleInput\x1B[0m';
-
-      expect(blue.wrap(sampleInput), expected);
-    });
-
-    test("empty", () {
-      expect(blue.wrap(''), '');
-    });
-
-    test(null, () {
-      expect(blue.wrap(null), isNull);
-    });
-  });
-
-  group('wrapWith', () {
-    _test("foreground", () {
-      final expected = '\x1B[34m$sampleInput\x1B[0m';
-
-      expect(wrapWith(sampleInput, [blue]), expected);
-    });
-
-    _test("background", () {
-      final expected = '\x1B[44m$sampleInput\x1B[0m';
-
-      expect(wrapWith(sampleInput, [backgroundBlue]), expected);
-    });
-
-    _test("style", () {
-      final expected = '\x1B[1m$sampleInput\x1B[0m';
-
-      expect(wrapWith(sampleInput, [styleBold]), expected);
-    });
-
-    _test("2 styles", () {
-      final expected = '\x1B[1;3m$sampleInput\x1B[0m';
-
-      expect(wrapWith(sampleInput, [styleBold, styleItalic]), expected);
-    });
-
-    _test("2 foregrounds", () {
-      expect(() => wrapWith(sampleInput, [blue, white]), throwsArgumentError);
-    });
-
-    _test("multi", () {
-      final expected = '\x1B[1;4;34;107m$sampleInput\x1B[0m';
-
-      expect(
-          wrapWith(
-              sampleInput, [blue, backgroundWhite, styleBold, styleUnderlined]),
-          expected);
-    });
-
-    test('no codes', () {
-      expect(wrapWith(sampleInput, []), sampleInput);
-    });
-
-    _test("empty", () {
-      expect(wrapWith('', [blue, backgroundWhite, styleBold]), '');
-    });
-
-    _test(null, () {
-      expect(wrapWith(null, [blue, backgroundWhite, styleBold]), isNull);
-    });
-  });
+  }
 }
 
 void _test<T>(String name, T body()) =>