Add a GlyphSet class (#7)

This makes it easier for a class or function to control whether it
individually uses ASCII or Unicode glyphs.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ee5e6f..7b73fc8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 1.1.0
+
+* Add a `GlyphSet` class that can be used to easily choose which set of glyphs
+  to use for a particular chunk of code.
+
+* Add `asciiGlyphs`, `unicodeGlyphs`, and `glyphs` getters that provide access
+  to `GlyphSet`s.
+
 ## 1.0.1
 
 * Set max SDK version to `<3.0.0`.
diff --git a/README.md b/README.md
index 5459994..0d5b78c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
 This library contains getters for useful Unicode glyphs as well as plain ASCII
 alternatives. It's intended to be used in command-line applications that may run
-on Windows and libraries that may be used by those applications.
+in places where Unicode isn't well-supported and libraries that may be used by
+those applications.
 
 We recommend that you import this library with the prefix "glyph". For example:
 
@@ -14,12 +15,12 @@
 
 ## ASCII Mode
 
-The default Windows `cmd.exe` shell is unable to display Unicode characters, so
-this package is able to transparently switch its glyphs to ASCII alternatives by
-setting [the `ascii` attribute][ascii]. When this attribute is `true`, all
-glyphs use ASCII characters instead. It currently defaults to `false`, although
-in the future it may default to `true` for applications running on the Dart VM
-on Windows. For example:
+Some shells are unable to display Unicode characters, so this package is able to
+transparently switch its glyphs to ASCII alternatives by setting [the `ascii`
+attribute][ascii]. When this attribute is `true`, all glyphs use ASCII
+characters instead. It currently defaults to `false`, although in the future it
+may default to `true` for applications running on the Dart VM on Windows. For
+example:
 
 [ascii]: https://www.dartdocs.org/documentation/term_glyph/latest/term_glyph/ascii.html
 
diff --git a/lib/src/generated.dart b/lib/src/generated.dart
deleted file mode 100644
index e1b83d1..0000000
--- a/lib/src/generated.dart
+++ /dev/null
@@ -1,564 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Don't modify this file by hand! It's generated by tool/generate.dart.
-
-/// Whether the glyph getters return plain ASCII, as opposed to Unicode
-/// characters or sequences.
-///
-/// Defaults to `false`.
-bool get ascii => _ascii;
-var _ascii = false;
-set ascii(bool value) {
-  _ascii = value;
-  if (value) {
-    _bullet = "*";
-    _leftArrow = "<";
-    _rightArrow = ">";
-    _upArrow = "^";
-    _downArrow = "v";
-    _longLeftArrow = "<=";
-    _longRightArrow = "=>";
-    _horizontalLine = "-";
-    _verticalLine = "|";
-    _topLeftCorner = ",";
-    _topRightCorner = ",";
-    _bottomLeftCorner = "'";
-    _bottomRightCorner = "'";
-    _cross = "+";
-    _teeUp = "+";
-    _teeDown = "+";
-    _teeLeft = "+";
-    _teeRight = "+";
-    _upEnd = "'";
-    _downEnd = ",";
-    _leftEnd = "-";
-    _rightEnd = "-";
-    _horizontalLineBold = "=";
-    _verticalLineBold = "|";
-    _topLeftCornerBold = ",";
-    _topRightCornerBold = ",";
-    _bottomLeftCornerBold = "'";
-    _bottomRightCornerBold = "'";
-    _crossBold = "+";
-    _teeUpBold = "+";
-    _teeDownBold = "+";
-    _teeLeftBold = "+";
-    _teeRightBold = "+";
-    _upEndBold = "'";
-    _downEndBold = ",";
-    _leftEndBold = "-";
-    _rightEndBold = "-";
-    _horizontalLineDouble = "=";
-    _verticalLineDouble = "|";
-    _topLeftCornerDouble = ",";
-    _topRightCornerDouble = ",";
-    _bottomLeftCornerDouble = '"';
-    _bottomRightCornerDouble = '"';
-    _crossDouble = "+";
-    _teeUpDouble = "+";
-    _teeDownDouble = "+";
-    _teeLeftDouble = "+";
-    _teeRightDouble = "+";
-    _horizontalLineDoubleDash = "-";
-    _horizontalLineDoubleDashBold = "-";
-    _verticalLineDoubleDash = "|";
-    _verticalLineDoubleDashBold = "|";
-    _horizontalLineTripleDash = "-";
-    _horizontalLineTripleDashBold = "-";
-    _verticalLineTripleDash = "|";
-    _verticalLineTripleDashBold = "|";
-    _horizontalLineQuadrupleDash = "-";
-    _horizontalLineQuadrupleDashBold = "-";
-    _verticalLineQuadrupleDash = "|";
-    _verticalLineQuadrupleDashBold = "|";
-  } else {
-    _bullet = "•";
-    _leftArrow = "←";
-    _rightArrow = "→";
-    _upArrow = "↑";
-    _downArrow = "↓";
-    _longLeftArrow = "◀━";
-    _longRightArrow = "━▶";
-    _horizontalLine = "─";
-    _verticalLine = "│";
-    _topLeftCorner = "┌";
-    _topRightCorner = "┐";
-    _bottomLeftCorner = "└";
-    _bottomRightCorner = "┘";
-    _cross = "┼";
-    _teeUp = "┴";
-    _teeDown = "┬";
-    _teeLeft = "┤";
-    _teeRight = "├";
-    _upEnd = "╵";
-    _downEnd = "╷";
-    _leftEnd = "╴";
-    _rightEnd = "╶";
-    _horizontalLineBold = "━";
-    _verticalLineBold = "┃";
-    _topLeftCornerBold = "┏";
-    _topRightCornerBold = "┓";
-    _bottomLeftCornerBold = "┗";
-    _bottomRightCornerBold = "┛";
-    _crossBold = "╋";
-    _teeUpBold = "┻";
-    _teeDownBold = "┳";
-    _teeLeftBold = "┫";
-    _teeRightBold = "┣";
-    _upEndBold = "╹";
-    _downEndBold = "╻";
-    _leftEndBold = "╸";
-    _rightEndBold = "╺";
-    _horizontalLineDouble = "═";
-    _verticalLineDouble = "║";
-    _topLeftCornerDouble = "╔";
-    _topRightCornerDouble = "╗";
-    _bottomLeftCornerDouble = "╚";
-    _bottomRightCornerDouble = "╝";
-    _crossDouble = "╬";
-    _teeUpDouble = "╩";
-    _teeDownDouble = "╦";
-    _teeLeftDouble = "╣";
-    _teeRightDouble = "╠";
-    _horizontalLineDoubleDash = "╌";
-    _horizontalLineDoubleDashBold = "╍";
-    _verticalLineDoubleDash = "╎";
-    _verticalLineDoubleDashBold = "╏";
-    _horizontalLineTripleDash = "┄";
-    _horizontalLineTripleDashBold = "┅";
-    _verticalLineTripleDash = "┆";
-    _verticalLineTripleDashBold = "┇";
-    _horizontalLineQuadrupleDash = "┈";
-    _horizontalLineQuadrupleDashBold = "┉";
-    _verticalLineQuadrupleDash = "┊";
-    _verticalLineQuadrupleDashBold = "┋";
-  }
-}
-
-/// A bullet point.
-///
-/// If [ascii] is `false`, this is "•". If it's `true`, this is
-/// "*" instead.
-String get bullet => _bullet;
-var _bullet = "•";
-
-/// A left-pointing arrow.
-///
-/// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
-/// terminal fonts, and should generally be surrounding by spaces.
-///
-/// If [ascii] is `false`, this is "←". If it's `true`, this is
-/// "<" instead.
-String get leftArrow => _leftArrow;
-var _leftArrow = "←";
-
-/// A right-pointing arrow.
-///
-/// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
-/// terminal fonts, and should generally be surrounding by spaces.
-///
-/// If [ascii] is `false`, this is "→". If it's `true`, this is
-/// ">" instead.
-String get rightArrow => _rightArrow;
-var _rightArrow = "→";
-
-/// An upwards-pointing arrow.
-///
-/// If [ascii] is `false`, this is "↑". If it's `true`, this is
-/// "^" instead.
-String get upArrow => _upArrow;
-var _upArrow = "↑";
-
-/// A downwards-pointing arrow.
-///
-/// If [ascii] is `false`, this is "↓". If it's `true`, this is
-/// "v" instead.
-String get downArrow => _downArrow;
-var _downArrow = "↓";
-
-/// A two-character left-pointing arrow.
-///
-/// If [ascii] is `false`, this is "◀━". If it's `true`, this is
-/// "<=" instead.
-String get longLeftArrow => _longLeftArrow;
-var _longLeftArrow = "◀━";
-
-/// A two-character right-pointing arrow.
-///
-/// If [ascii] is `false`, this is "━▶". If it's `true`, this is
-/// "=>" instead.
-String get longRightArrow => _longRightArrow;
-var _longRightArrow = "━▶";
-
-/// A horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "─". If it's `true`, this is
-/// "-" instead.
-String get horizontalLine => _horizontalLine;
-var _horizontalLine = "─";
-
-/// A vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "│". If it's `true`, this is
-/// "|" instead.
-String get verticalLine => _verticalLine;
-var _verticalLine = "│";
-
-/// The upper left-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "┌". If it's `true`, this is
-/// "," instead.
-String get topLeftCorner => _topLeftCorner;
-var _topLeftCorner = "┌";
-
-/// The upper right-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "┐". If it's `true`, this is
-/// "," instead.
-String get topRightCorner => _topRightCorner;
-var _topRightCorner = "┐";
-
-/// The lower left-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "└". If it's `true`, this is
-/// "'" instead.
-String get bottomLeftCorner => _bottomLeftCorner;
-var _bottomLeftCorner = "└";
-
-/// The lower right-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "┘". If it's `true`, this is
-/// "'" instead.
-String get bottomRightCorner => _bottomRightCorner;
-var _bottomRightCorner = "┘";
-
-/// An intersection of vertical and horizontal box lines.
-///
-/// If [ascii] is `false`, this is "┼". If it's `true`, this is
-/// "+" instead.
-String get cross => _cross;
-var _cross = "┼";
-
-/// A horizontal box line with a vertical line going up from the middle.
-///
-/// If [ascii] is `false`, this is "┴". If it's `true`, this is
-/// "+" instead.
-String get teeUp => _teeUp;
-var _teeUp = "┴";
-
-/// A horizontal box line with a vertical line going down from the middle.
-///
-/// If [ascii] is `false`, this is "┬". If it's `true`, this is
-/// "+" instead.
-String get teeDown => _teeDown;
-var _teeDown = "┬";
-
-/// A vertical box line with a horizontal line going left from the middle.
-///
-/// If [ascii] is `false`, this is "┤". If it's `true`, this is
-/// "+" instead.
-String get teeLeft => _teeLeft;
-var _teeLeft = "┤";
-
-/// A vertical box line with a horizontal line going right from the middle.
-///
-/// If [ascii] is `false`, this is "├". If it's `true`, this is
-/// "+" instead.
-String get teeRight => _teeRight;
-var _teeRight = "├";
-
-/// The top half of a vertical box line.
-///
-/// If [ascii] is `false`, this is "╵". If it's `true`, this is
-/// "'" instead.
-String get upEnd => _upEnd;
-var _upEnd = "╵";
-
-/// The bottom half of a vertical box line.
-///
-/// If [ascii] is `false`, this is "╷". If it's `true`, this is
-/// "," instead.
-String get downEnd => _downEnd;
-var _downEnd = "╷";
-
-/// The left half of a horizontal box line.
-///
-/// If [ascii] is `false`, this is "╴". If it's `true`, this is
-/// "-" instead.
-String get leftEnd => _leftEnd;
-var _leftEnd = "╴";
-
-/// The right half of a horizontal box line.
-///
-/// If [ascii] is `false`, this is "╶". If it's `true`, this is
-/// "-" instead.
-String get rightEnd => _rightEnd;
-var _rightEnd = "╶";
-
-/// A bold horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "━". If it's `true`, this is
-/// "=" instead.
-String get horizontalLineBold => _horizontalLineBold;
-var _horizontalLineBold = "━";
-
-/// A bold vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┃". If it's `true`, this is
-/// "|" instead.
-String get verticalLineBold => _verticalLineBold;
-var _verticalLineBold = "┃";
-
-/// The bold upper left-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "┏". If it's `true`, this is
-/// "," instead.
-String get topLeftCornerBold => _topLeftCornerBold;
-var _topLeftCornerBold = "┏";
-
-/// The bold upper right-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "┓". If it's `true`, this is
-/// "," instead.
-String get topRightCornerBold => _topRightCornerBold;
-var _topRightCornerBold = "┓";
-
-/// The bold lower left-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "┗". If it's `true`, this is
-/// "'" instead.
-String get bottomLeftCornerBold => _bottomLeftCornerBold;
-var _bottomLeftCornerBold = "┗";
-
-/// The bold lower right-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "┛". If it's `true`, this is
-/// "'" instead.
-String get bottomRightCornerBold => _bottomRightCornerBold;
-var _bottomRightCornerBold = "┛";
-
-/// An intersection of bold vertical and horizontal box lines.
-///
-/// If [ascii] is `false`, this is "╋". If it's `true`, this is
-/// "+" instead.
-String get crossBold => _crossBold;
-var _crossBold = "╋";
-
-/// A bold horizontal box line with a vertical line going up from the middle.
-///
-/// If [ascii] is `false`, this is "┻". If it's `true`, this is
-/// "+" instead.
-String get teeUpBold => _teeUpBold;
-var _teeUpBold = "┻";
-
-/// A bold horizontal box line with a vertical line going down from the middle.
-///
-/// If [ascii] is `false`, this is "┳". If it's `true`, this is
-/// "+" instead.
-String get teeDownBold => _teeDownBold;
-var _teeDownBold = "┳";
-
-/// A bold vertical box line with a horizontal line going left from the middle.
-///
-/// If [ascii] is `false`, this is "┫". If it's `true`, this is
-/// "+" instead.
-String get teeLeftBold => _teeLeftBold;
-var _teeLeftBold = "┫";
-
-/// A bold vertical box line with a horizontal line going right from the middle.
-///
-/// If [ascii] is `false`, this is "┣". If it's `true`, this is
-/// "+" instead.
-String get teeRightBold => _teeRightBold;
-var _teeRightBold = "┣";
-
-/// The top half of a bold vertical box line.
-///
-/// If [ascii] is `false`, this is "╹". If it's `true`, this is
-/// "'" instead.
-String get upEndBold => _upEndBold;
-var _upEndBold = "╹";
-
-/// The bottom half of a bold vertical box line.
-///
-/// If [ascii] is `false`, this is "╻". If it's `true`, this is
-/// "," instead.
-String get downEndBold => _downEndBold;
-var _downEndBold = "╻";
-
-/// The left half of a bold horizontal box line.
-///
-/// If [ascii] is `false`, this is "╸". If it's `true`, this is
-/// "-" instead.
-String get leftEndBold => _leftEndBold;
-var _leftEndBold = "╸";
-
-/// The right half of a bold horizontal box line.
-///
-/// If [ascii] is `false`, this is "╺". If it's `true`, this is
-/// "-" instead.
-String get rightEndBold => _rightEndBold;
-var _rightEndBold = "╺";
-
-/// A double horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "═". If it's `true`, this is
-/// "=" instead.
-String get horizontalLineDouble => _horizontalLineDouble;
-var _horizontalLineDouble = "═";
-
-/// A double vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "║". If it's `true`, this is
-/// "|" instead.
-String get verticalLineDouble => _verticalLineDouble;
-var _verticalLineDouble = "║";
-
-/// The double upper left-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "╔". If it's `true`, this is
-/// "," instead.
-String get topLeftCornerDouble => _topLeftCornerDouble;
-var _topLeftCornerDouble = "╔";
-
-/// The double upper right-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "╗". If it's `true`, this is
-/// "," instead.
-String get topRightCornerDouble => _topRightCornerDouble;
-var _topRightCornerDouble = "╗";
-
-/// The double lower left-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "╚". If it's `true`, this is
-/// """ instead.
-String get bottomLeftCornerDouble => _bottomLeftCornerDouble;
-var _bottomLeftCornerDouble = "╚";
-
-/// The double lower right-hand corner of a box.
-///
-/// If [ascii] is `false`, this is "╝". If it's `true`, this is
-/// """ instead.
-String get bottomRightCornerDouble => _bottomRightCornerDouble;
-var _bottomRightCornerDouble = "╝";
-
-/// An intersection of double vertical and horizontal box lines.
-///
-/// If [ascii] is `false`, this is "╬". If it's `true`, this is
-/// "+" instead.
-String get crossDouble => _crossDouble;
-var _crossDouble = "╬";
-
-/// A double horizontal box line with a vertical line going up from the middle.
-///
-/// If [ascii] is `false`, this is "╩". If it's `true`, this is
-/// "+" instead.
-String get teeUpDouble => _teeUpDouble;
-var _teeUpDouble = "╩";
-
-/// A double horizontal box line with a vertical line going down from the middle.
-///
-/// If [ascii] is `false`, this is "╦". If it's `true`, this is
-/// "+" instead.
-String get teeDownDouble => _teeDownDouble;
-var _teeDownDouble = "╦";
-
-/// A double vertical box line with a horizontal line going left from the middle.
-///
-/// If [ascii] is `false`, this is "╣". If it's `true`, this is
-/// "+" instead.
-String get teeLeftDouble => _teeLeftDouble;
-var _teeLeftDouble = "╣";
-
-/// A double vertical box line with a horizontal line going right from the middle.
-///
-/// If [ascii] is `false`, this is "╠". If it's `true`, this is
-/// "+" instead.
-String get teeRightDouble => _teeRightDouble;
-var _teeRightDouble = "╠";
-
-/// A dashed horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "╌". If it's `true`, this is
-/// "-" instead.
-String get horizontalLineDoubleDash => _horizontalLineDoubleDash;
-var _horizontalLineDoubleDash = "╌";
-
-/// A bold dashed horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "╍". If it's `true`, this is
-/// "-" instead.
-String get horizontalLineDoubleDashBold => _horizontalLineDoubleDashBold;
-var _horizontalLineDoubleDashBold = "╍";
-
-/// A dashed vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "╎". If it's `true`, this is
-/// "|" instead.
-String get verticalLineDoubleDash => _verticalLineDoubleDash;
-var _verticalLineDoubleDash = "╎";
-
-/// A bold dashed vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "╏". If it's `true`, this is
-/// "|" instead.
-String get verticalLineDoubleDashBold => _verticalLineDoubleDashBold;
-var _verticalLineDoubleDashBold = "╏";
-
-/// A dashed horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┄". If it's `true`, this is
-/// "-" instead.
-String get horizontalLineTripleDash => _horizontalLineTripleDash;
-var _horizontalLineTripleDash = "┄";
-
-/// A bold dashed horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┅". If it's `true`, this is
-/// "-" instead.
-String get horizontalLineTripleDashBold => _horizontalLineTripleDashBold;
-var _horizontalLineTripleDashBold = "┅";
-
-/// A dashed vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┆". If it's `true`, this is
-/// "|" instead.
-String get verticalLineTripleDash => _verticalLineTripleDash;
-var _verticalLineTripleDash = "┆";
-
-/// A bold dashed vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┇". If it's `true`, this is
-/// "|" instead.
-String get verticalLineTripleDashBold => _verticalLineTripleDashBold;
-var _verticalLineTripleDashBold = "┇";
-
-/// A dashed horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┈". If it's `true`, this is
-/// "-" instead.
-String get horizontalLineQuadrupleDash => _horizontalLineQuadrupleDash;
-var _horizontalLineQuadrupleDash = "┈";
-
-/// A bold dashed horizontal line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┉". If it's `true`, this is
-/// "-" instead.
-String get horizontalLineQuadrupleDashBold => _horizontalLineQuadrupleDashBold;
-var _horizontalLineQuadrupleDashBold = "┉";
-
-/// A dashed vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┊". If it's `true`, this is
-/// "|" instead.
-String get verticalLineQuadrupleDash => _verticalLineQuadrupleDash;
-var _verticalLineQuadrupleDash = "┊";
-
-/// A bold dashed vertical line that can be used to draw a box.
-///
-/// If [ascii] is `false`, this is "┋". If it's `true`, this is
-/// "|" instead.
-String get verticalLineQuadrupleDashBold => _verticalLineQuadrupleDashBold;
-var _verticalLineQuadrupleDashBold = "┋";
diff --git a/lib/src/generated/ascii_glyph_set.dart b/lib/src/generated/ascii_glyph_set.dart
new file mode 100644
index 0000000..f470fe4
--- /dev/null
+++ b/lib/src/generated/ascii_glyph_set.dart
@@ -0,0 +1,322 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Don't modify this file by hand! It's generated by tool/generate.dart.
+
+import 'glyph_set.dart';
+
+/// A [GlyphSet] that includes only ASCII glyphs.
+class AsciiGlyphSet implements GlyphSet {
+  const AsciiGlyphSet();
+
+  /// Returns [glyph] if [this] supports Unicode glyphs and [alternative]
+  /// otherwise.
+  String glyphOrAscii(String glyph, String alternative) => alternative;
+
+  /// A bullet point.
+  ///
+  /// Always "*" for [this].
+  String get bullet => "*";
+
+  /// A left-pointing arrow.
+  ///
+  /// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+  /// terminal fonts, and should generally be surrounding by spaces.
+  ///
+  /// Always "<" for [this].
+  String get leftArrow => "<";
+
+  /// A right-pointing arrow.
+  ///
+  /// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+  /// terminal fonts, and should generally be surrounding by spaces.
+  ///
+  /// Always ">" for [this].
+  String get rightArrow => ">";
+
+  /// An upwards-pointing arrow.
+  ///
+  /// Always "^" for [this].
+  String get upArrow => "^";
+
+  /// A downwards-pointing arrow.
+  ///
+  /// Always "v" for [this].
+  String get downArrow => "v";
+
+  /// A two-character left-pointing arrow.
+  ///
+  /// Always "<=" for [this].
+  String get longLeftArrow => "<=";
+
+  /// A two-character right-pointing arrow.
+  ///
+  /// Always "=>" for [this].
+  String get longRightArrow => "=>";
+
+  /// A horizontal line that can be used to draw a box.
+  ///
+  /// Always "-" for [this].
+  String get horizontalLine => "-";
+
+  /// A vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLine => "|";
+
+  /// The upper left-hand corner of a box.
+  ///
+  /// Always "," for [this].
+  String get topLeftCorner => ",";
+
+  /// The upper right-hand corner of a box.
+  ///
+  /// Always "," for [this].
+  String get topRightCorner => ",";
+
+  /// The lower left-hand corner of a box.
+  ///
+  /// Always "'" for [this].
+  String get bottomLeftCorner => "'";
+
+  /// The lower right-hand corner of a box.
+  ///
+  /// Always "'" for [this].
+  String get bottomRightCorner => "'";
+
+  /// An intersection of vertical and horizontal box lines.
+  ///
+  /// Always "+" for [this].
+  String get cross => "+";
+
+  /// A horizontal box line with a vertical line going up from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeUp => "+";
+
+  /// A horizontal box line with a vertical line going down from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeDown => "+";
+
+  /// A vertical box line with a horizontal line going left from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeLeft => "+";
+
+  /// A vertical box line with a horizontal line going right from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeRight => "+";
+
+  /// The top half of a vertical box line.
+  ///
+  /// Always "'" for [this].
+  String get upEnd => "'";
+
+  /// The bottom half of a vertical box line.
+  ///
+  /// Always "," for [this].
+  String get downEnd => ",";
+
+  /// The left half of a horizontal box line.
+  ///
+  /// Always "-" for [this].
+  String get leftEnd => "-";
+
+  /// The right half of a horizontal box line.
+  ///
+  /// Always "-" for [this].
+  String get rightEnd => "-";
+
+  /// A bold horizontal line that can be used to draw a box.
+  ///
+  /// Always "=" for [this].
+  String get horizontalLineBold => "=";
+
+  /// A bold vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineBold => "|";
+
+  /// The bold upper left-hand corner of a box.
+  ///
+  /// Always "," for [this].
+  String get topLeftCornerBold => ",";
+
+  /// The bold upper right-hand corner of a box.
+  ///
+  /// Always "," for [this].
+  String get topRightCornerBold => ",";
+
+  /// The bold lower left-hand corner of a box.
+  ///
+  /// Always "'" for [this].
+  String get bottomLeftCornerBold => "'";
+
+  /// The bold lower right-hand corner of a box.
+  ///
+  /// Always "'" for [this].
+  String get bottomRightCornerBold => "'";
+
+  /// An intersection of bold vertical and horizontal box lines.
+  ///
+  /// Always "+" for [this].
+  String get crossBold => "+";
+
+  /// A bold horizontal box line with a vertical line going up from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeUpBold => "+";
+
+  /// A bold horizontal box line with a vertical line going down from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeDownBold => "+";
+
+  /// A bold vertical box line with a horizontal line going left from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeLeftBold => "+";
+
+  /// A bold vertical box line with a horizontal line going right from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeRightBold => "+";
+
+  /// The top half of a bold vertical box line.
+  ///
+  /// Always "'" for [this].
+  String get upEndBold => "'";
+
+  /// The bottom half of a bold vertical box line.
+  ///
+  /// Always "," for [this].
+  String get downEndBold => ",";
+
+  /// The left half of a bold horizontal box line.
+  ///
+  /// Always "-" for [this].
+  String get leftEndBold => "-";
+
+  /// The right half of a bold horizontal box line.
+  ///
+  /// Always "-" for [this].
+  String get rightEndBold => "-";
+
+  /// A double horizontal line that can be used to draw a box.
+  ///
+  /// Always "=" for [this].
+  String get horizontalLineDouble => "=";
+
+  /// A double vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineDouble => "|";
+
+  /// The double upper left-hand corner of a box.
+  ///
+  /// Always "," for [this].
+  String get topLeftCornerDouble => ",";
+
+  /// The double upper right-hand corner of a box.
+  ///
+  /// Always "," for [this].
+  String get topRightCornerDouble => ",";
+
+  /// The double lower left-hand corner of a box.
+  ///
+  /// Always '"' for [this].
+  String get bottomLeftCornerDouble => '"';
+
+  /// The double lower right-hand corner of a box.
+  ///
+  /// Always '"' for [this].
+  String get bottomRightCornerDouble => '"';
+
+  /// An intersection of double vertical and horizontal box lines.
+  ///
+  /// Always "+" for [this].
+  String get crossDouble => "+";
+
+  /// A double horizontal box line with a vertical line going up from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeUpDouble => "+";
+
+  /// A double horizontal box line with a vertical line going down from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeDownDouble => "+";
+
+  /// A double vertical box line with a horizontal line going left from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeLeftDouble => "+";
+
+  /// A double vertical box line with a horizontal line going right from the middle.
+  ///
+  /// Always "+" for [this].
+  String get teeRightDouble => "+";
+
+  /// A dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "-" for [this].
+  String get horizontalLineDoubleDash => "-";
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "-" for [this].
+  String get horizontalLineDoubleDashBold => "-";
+
+  /// A dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineDoubleDash => "|";
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineDoubleDashBold => "|";
+
+  /// A dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "-" for [this].
+  String get horizontalLineTripleDash => "-";
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "-" for [this].
+  String get horizontalLineTripleDashBold => "-";
+
+  /// A dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineTripleDash => "|";
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineTripleDashBold => "|";
+
+  /// A dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "-" for [this].
+  String get horizontalLineQuadrupleDash => "-";
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "-" for [this].
+  String get horizontalLineQuadrupleDashBold => "-";
+
+  /// A dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineQuadrupleDash => "|";
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "|" for [this].
+  String get verticalLineQuadrupleDashBold => "|";
+}
diff --git a/lib/src/generated/glyph_set.dart b/lib/src/generated/glyph_set.dart
new file mode 100644
index 0000000..93676db
--- /dev/null
+++ b/lib/src/generated/glyph_set.dart
@@ -0,0 +1,220 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Don't modify this file by hand! It's generated by tool/generate.dart.
+
+/// A class that provides access to every configurable glyph.
+///
+/// This is provided as a class so that individual chunks of code can choose
+/// between [ascii] and [unicode] glyphs. For example:
+///
+/// ```dart
+/// import 'package:term_glyph/term_glyph.dart' as glyph;
+///
+/// /// Adds a vertical line to the left of [text].
+/// ///
+/// /// If [ascii] is `true`, this uses plain ASCII for the line. If it's
+/// /// `false`, this uses Unicode characters. If it's `null`, it defaults
+/// /// to [glyph.ascii].
+/// void addVerticalLine(String text, {bool ascii}) {
+///   var glyphs =
+///       (ascii ?? glyph.ascii) ? glyph.asciiGlyphs : glyph.unicodeGlyphs;
+///
+///   return text
+///       .split("\n")
+///       .map((line) => "${glyphs.verticalLine} $line")
+///       .join("\n");
+/// }
+/// ```
+abstract class GlyphSet {
+  /// Returns [glyph] if [this] supports Unicode glyphs and [alternative]
+  /// otherwise.
+  String glyphOrAscii(String glyph, String alternative);
+
+  /// A bullet point.
+  String get bullet;
+
+  /// A left-pointing arrow.
+  ///
+  /// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+  /// terminal fonts, and should generally be surrounding by spaces.
+  String get leftArrow;
+
+  /// A right-pointing arrow.
+  ///
+  /// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+  /// terminal fonts, and should generally be surrounding by spaces.
+  String get rightArrow;
+
+  /// An upwards-pointing arrow.
+  String get upArrow;
+
+  /// A downwards-pointing arrow.
+  String get downArrow;
+
+  /// A two-character left-pointing arrow.
+  String get longLeftArrow;
+
+  /// A two-character right-pointing arrow.
+  String get longRightArrow;
+
+  /// A horizontal line that can be used to draw a box.
+  String get horizontalLine;
+
+  /// A vertical line that can be used to draw a box.
+  String get verticalLine;
+
+  /// The upper left-hand corner of a box.
+  String get topLeftCorner;
+
+  /// The upper right-hand corner of a box.
+  String get topRightCorner;
+
+  /// The lower left-hand corner of a box.
+  String get bottomLeftCorner;
+
+  /// The lower right-hand corner of a box.
+  String get bottomRightCorner;
+
+  /// An intersection of vertical and horizontal box lines.
+  String get cross;
+
+  /// A horizontal box line with a vertical line going up from the middle.
+  String get teeUp;
+
+  /// A horizontal box line with a vertical line going down from the middle.
+  String get teeDown;
+
+  /// A vertical box line with a horizontal line going left from the middle.
+  String get teeLeft;
+
+  /// A vertical box line with a horizontal line going right from the middle.
+  String get teeRight;
+
+  /// The top half of a vertical box line.
+  String get upEnd;
+
+  /// The bottom half of a vertical box line.
+  String get downEnd;
+
+  /// The left half of a horizontal box line.
+  String get leftEnd;
+
+  /// The right half of a horizontal box line.
+  String get rightEnd;
+
+  /// A bold horizontal line that can be used to draw a box.
+  String get horizontalLineBold;
+
+  /// A bold vertical line that can be used to draw a box.
+  String get verticalLineBold;
+
+  /// The bold upper left-hand corner of a box.
+  String get topLeftCornerBold;
+
+  /// The bold upper right-hand corner of a box.
+  String get topRightCornerBold;
+
+  /// The bold lower left-hand corner of a box.
+  String get bottomLeftCornerBold;
+
+  /// The bold lower right-hand corner of a box.
+  String get bottomRightCornerBold;
+
+  /// An intersection of bold vertical and horizontal box lines.
+  String get crossBold;
+
+  /// A bold horizontal box line with a vertical line going up from the middle.
+  String get teeUpBold;
+
+  /// A bold horizontal box line with a vertical line going down from the middle.
+  String get teeDownBold;
+
+  /// A bold vertical box line with a horizontal line going left from the middle.
+  String get teeLeftBold;
+
+  /// A bold vertical box line with a horizontal line going right from the middle.
+  String get teeRightBold;
+
+  /// The top half of a bold vertical box line.
+  String get upEndBold;
+
+  /// The bottom half of a bold vertical box line.
+  String get downEndBold;
+
+  /// The left half of a bold horizontal box line.
+  String get leftEndBold;
+
+  /// The right half of a bold horizontal box line.
+  String get rightEndBold;
+
+  /// A double horizontal line that can be used to draw a box.
+  String get horizontalLineDouble;
+
+  /// A double vertical line that can be used to draw a box.
+  String get verticalLineDouble;
+
+  /// The double upper left-hand corner of a box.
+  String get topLeftCornerDouble;
+
+  /// The double upper right-hand corner of a box.
+  String get topRightCornerDouble;
+
+  /// The double lower left-hand corner of a box.
+  String get bottomLeftCornerDouble;
+
+  /// The double lower right-hand corner of a box.
+  String get bottomRightCornerDouble;
+
+  /// An intersection of double vertical and horizontal box lines.
+  String get crossDouble;
+
+  /// A double horizontal box line with a vertical line going up from the middle.
+  String get teeUpDouble;
+
+  /// A double horizontal box line with a vertical line going down from the middle.
+  String get teeDownDouble;
+
+  /// A double vertical box line with a horizontal line going left from the middle.
+  String get teeLeftDouble;
+
+  /// A double vertical box line with a horizontal line going right from the middle.
+  String get teeRightDouble;
+
+  /// A dashed horizontal line that can be used to draw a box.
+  String get horizontalLineDoubleDash;
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  String get horizontalLineDoubleDashBold;
+
+  /// A dashed vertical line that can be used to draw a box.
+  String get verticalLineDoubleDash;
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  String get verticalLineDoubleDashBold;
+
+  /// A dashed horizontal line that can be used to draw a box.
+  String get horizontalLineTripleDash;
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  String get horizontalLineTripleDashBold;
+
+  /// A dashed vertical line that can be used to draw a box.
+  String get verticalLineTripleDash;
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  String get verticalLineTripleDashBold;
+
+  /// A dashed horizontal line that can be used to draw a box.
+  String get horizontalLineQuadrupleDash;
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  String get horizontalLineQuadrupleDashBold;
+
+  /// A dashed vertical line that can be used to draw a box.
+  String get verticalLineQuadrupleDash;
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  String get verticalLineQuadrupleDashBold;
+}
diff --git a/lib/src/generated/top_level.dart b/lib/src/generated/top_level.dart
new file mode 100644
index 0000000..9475953
--- /dev/null
+++ b/lib/src/generated/top_level.dart
@@ -0,0 +1,380 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Don't modify this file by hand! It's generated by tool/generate.dart.
+
+import '../../term_glyph.dart' as glyph;
+
+/// A bullet point.
+///
+/// If [ascii] is `false`, this is "•". If it's `true`, this is
+/// "*" instead.
+String get bullet => glyph.glyphs.bullet;
+
+/// A left-pointing arrow.
+///
+/// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+/// terminal fonts, and should generally be surrounding by spaces.
+///
+/// If [ascii] is `false`, this is "←". If it's `true`, this is
+/// "<" instead.
+String get leftArrow => glyph.glyphs.leftArrow;
+
+/// A right-pointing arrow.
+///
+/// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+/// terminal fonts, and should generally be surrounding by spaces.
+///
+/// If [ascii] is `false`, this is "→". If it's `true`, this is
+/// ">" instead.
+String get rightArrow => glyph.glyphs.rightArrow;
+
+/// An upwards-pointing arrow.
+///
+/// If [ascii] is `false`, this is "↑". If it's `true`, this is
+/// "^" instead.
+String get upArrow => glyph.glyphs.upArrow;
+
+/// A downwards-pointing arrow.
+///
+/// If [ascii] is `false`, this is "↓". If it's `true`, this is
+/// "v" instead.
+String get downArrow => glyph.glyphs.downArrow;
+
+/// A two-character left-pointing arrow.
+///
+/// If [ascii] is `false`, this is "◀━". If it's `true`, this is
+/// "<=" instead.
+String get longLeftArrow => glyph.glyphs.longLeftArrow;
+
+/// A two-character right-pointing arrow.
+///
+/// If [ascii] is `false`, this is "━▶". If it's `true`, this is
+/// "=>" instead.
+String get longRightArrow => glyph.glyphs.longRightArrow;
+
+/// A horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "─". If it's `true`, this is
+/// "-" instead.
+String get horizontalLine => glyph.glyphs.horizontalLine;
+
+/// A vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "│". If it's `true`, this is
+/// "|" instead.
+String get verticalLine => glyph.glyphs.verticalLine;
+
+/// The upper left-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "┌". If it's `true`, this is
+/// "," instead.
+String get topLeftCorner => glyph.glyphs.topLeftCorner;
+
+/// The upper right-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "┐". If it's `true`, this is
+/// "," instead.
+String get topRightCorner => glyph.glyphs.topRightCorner;
+
+/// The lower left-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "└". If it's `true`, this is
+/// "'" instead.
+String get bottomLeftCorner => glyph.glyphs.bottomLeftCorner;
+
+/// The lower right-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "┘". If it's `true`, this is
+/// "'" instead.
+String get bottomRightCorner => glyph.glyphs.bottomRightCorner;
+
+/// An intersection of vertical and horizontal box lines.
+///
+/// If [ascii] is `false`, this is "┼". If it's `true`, this is
+/// "+" instead.
+String get cross => glyph.glyphs.cross;
+
+/// A horizontal box line with a vertical line going up from the middle.
+///
+/// If [ascii] is `false`, this is "┴". If it's `true`, this is
+/// "+" instead.
+String get teeUp => glyph.glyphs.teeUp;
+
+/// A horizontal box line with a vertical line going down from the middle.
+///
+/// If [ascii] is `false`, this is "┬". If it's `true`, this is
+/// "+" instead.
+String get teeDown => glyph.glyphs.teeDown;
+
+/// A vertical box line with a horizontal line going left from the middle.
+///
+/// If [ascii] is `false`, this is "┤". If it's `true`, this is
+/// "+" instead.
+String get teeLeft => glyph.glyphs.teeLeft;
+
+/// A vertical box line with a horizontal line going right from the middle.
+///
+/// If [ascii] is `false`, this is "├". If it's `true`, this is
+/// "+" instead.
+String get teeRight => glyph.glyphs.teeRight;
+
+/// The top half of a vertical box line.
+///
+/// If [ascii] is `false`, this is "╵". If it's `true`, this is
+/// "'" instead.
+String get upEnd => glyph.glyphs.upEnd;
+
+/// The bottom half of a vertical box line.
+///
+/// If [ascii] is `false`, this is "╷". If it's `true`, this is
+/// "," instead.
+String get downEnd => glyph.glyphs.downEnd;
+
+/// The left half of a horizontal box line.
+///
+/// If [ascii] is `false`, this is "╴". If it's `true`, this is
+/// "-" instead.
+String get leftEnd => glyph.glyphs.leftEnd;
+
+/// The right half of a horizontal box line.
+///
+/// If [ascii] is `false`, this is "╶". If it's `true`, this is
+/// "-" instead.
+String get rightEnd => glyph.glyphs.rightEnd;
+
+/// A bold horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "━". If it's `true`, this is
+/// "=" instead.
+String get horizontalLineBold => glyph.glyphs.horizontalLineBold;
+
+/// A bold vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┃". If it's `true`, this is
+/// "|" instead.
+String get verticalLineBold => glyph.glyphs.verticalLineBold;
+
+/// The bold upper left-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "┏". If it's `true`, this is
+/// "," instead.
+String get topLeftCornerBold => glyph.glyphs.topLeftCornerBold;
+
+/// The bold upper right-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "┓". If it's `true`, this is
+/// "," instead.
+String get topRightCornerBold => glyph.glyphs.topRightCornerBold;
+
+/// The bold lower left-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "┗". If it's `true`, this is
+/// "'" instead.
+String get bottomLeftCornerBold => glyph.glyphs.bottomLeftCornerBold;
+
+/// The bold lower right-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "┛". If it's `true`, this is
+/// "'" instead.
+String get bottomRightCornerBold => glyph.glyphs.bottomRightCornerBold;
+
+/// An intersection of bold vertical and horizontal box lines.
+///
+/// If [ascii] is `false`, this is "╋". If it's `true`, this is
+/// "+" instead.
+String get crossBold => glyph.glyphs.crossBold;
+
+/// A bold horizontal box line with a vertical line going up from the middle.
+///
+/// If [ascii] is `false`, this is "┻". If it's `true`, this is
+/// "+" instead.
+String get teeUpBold => glyph.glyphs.teeUpBold;
+
+/// A bold horizontal box line with a vertical line going down from the middle.
+///
+/// If [ascii] is `false`, this is "┳". If it's `true`, this is
+/// "+" instead.
+String get teeDownBold => glyph.glyphs.teeDownBold;
+
+/// A bold vertical box line with a horizontal line going left from the middle.
+///
+/// If [ascii] is `false`, this is "┫". If it's `true`, this is
+/// "+" instead.
+String get teeLeftBold => glyph.glyphs.teeLeftBold;
+
+/// A bold vertical box line with a horizontal line going right from the middle.
+///
+/// If [ascii] is `false`, this is "┣". If it's `true`, this is
+/// "+" instead.
+String get teeRightBold => glyph.glyphs.teeRightBold;
+
+/// The top half of a bold vertical box line.
+///
+/// If [ascii] is `false`, this is "╹". If it's `true`, this is
+/// "'" instead.
+String get upEndBold => glyph.glyphs.upEndBold;
+
+/// The bottom half of a bold vertical box line.
+///
+/// If [ascii] is `false`, this is "╻". If it's `true`, this is
+/// "," instead.
+String get downEndBold => glyph.glyphs.downEndBold;
+
+/// The left half of a bold horizontal box line.
+///
+/// If [ascii] is `false`, this is "╸". If it's `true`, this is
+/// "-" instead.
+String get leftEndBold => glyph.glyphs.leftEndBold;
+
+/// The right half of a bold horizontal box line.
+///
+/// If [ascii] is `false`, this is "╺". If it's `true`, this is
+/// "-" instead.
+String get rightEndBold => glyph.glyphs.rightEndBold;
+
+/// A double horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "═". If it's `true`, this is
+/// "=" instead.
+String get horizontalLineDouble => glyph.glyphs.horizontalLineDouble;
+
+/// A double vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "║". If it's `true`, this is
+/// "|" instead.
+String get verticalLineDouble => glyph.glyphs.verticalLineDouble;
+
+/// The double upper left-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "╔". If it's `true`, this is
+/// "," instead.
+String get topLeftCornerDouble => glyph.glyphs.topLeftCornerDouble;
+
+/// The double upper right-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "╗". If it's `true`, this is
+/// "," instead.
+String get topRightCornerDouble => glyph.glyphs.topRightCornerDouble;
+
+/// The double lower left-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "╚". If it's `true`, this is
+/// """ instead.
+String get bottomLeftCornerDouble => glyph.glyphs.bottomLeftCornerDouble;
+
+/// The double lower right-hand corner of a box.
+///
+/// If [ascii] is `false`, this is "╝". If it's `true`, this is
+/// """ instead.
+String get bottomRightCornerDouble => glyph.glyphs.bottomRightCornerDouble;
+
+/// An intersection of double vertical and horizontal box lines.
+///
+/// If [ascii] is `false`, this is "╬". If it's `true`, this is
+/// "+" instead.
+String get crossDouble => glyph.glyphs.crossDouble;
+
+/// A double horizontal box line with a vertical line going up from the middle.
+///
+/// If [ascii] is `false`, this is "╩". If it's `true`, this is
+/// "+" instead.
+String get teeUpDouble => glyph.glyphs.teeUpDouble;
+
+/// A double horizontal box line with a vertical line going down from the middle.
+///
+/// If [ascii] is `false`, this is "╦". If it's `true`, this is
+/// "+" instead.
+String get teeDownDouble => glyph.glyphs.teeDownDouble;
+
+/// A double vertical box line with a horizontal line going left from the middle.
+///
+/// If [ascii] is `false`, this is "╣". If it's `true`, this is
+/// "+" instead.
+String get teeLeftDouble => glyph.glyphs.teeLeftDouble;
+
+/// A double vertical box line with a horizontal line going right from the middle.
+///
+/// If [ascii] is `false`, this is "╠". If it's `true`, this is
+/// "+" instead.
+String get teeRightDouble => glyph.glyphs.teeRightDouble;
+
+/// A dashed horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "╌". If it's `true`, this is
+/// "-" instead.
+String get horizontalLineDoubleDash => glyph.glyphs.horizontalLineDoubleDash;
+
+/// A bold dashed horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "╍". If it's `true`, this is
+/// "-" instead.
+String get horizontalLineDoubleDashBold =>
+    glyph.glyphs.horizontalLineDoubleDashBold;
+
+/// A dashed vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "╎". If it's `true`, this is
+/// "|" instead.
+String get verticalLineDoubleDash => glyph.glyphs.verticalLineDoubleDash;
+
+/// A bold dashed vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "╏". If it's `true`, this is
+/// "|" instead.
+String get verticalLineDoubleDashBold =>
+    glyph.glyphs.verticalLineDoubleDashBold;
+
+/// A dashed horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┄". If it's `true`, this is
+/// "-" instead.
+String get horizontalLineTripleDash => glyph.glyphs.horizontalLineTripleDash;
+
+/// A bold dashed horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┅". If it's `true`, this is
+/// "-" instead.
+String get horizontalLineTripleDashBold =>
+    glyph.glyphs.horizontalLineTripleDashBold;
+
+/// A dashed vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┆". If it's `true`, this is
+/// "|" instead.
+String get verticalLineTripleDash => glyph.glyphs.verticalLineTripleDash;
+
+/// A bold dashed vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┇". If it's `true`, this is
+/// "|" instead.
+String get verticalLineTripleDashBold =>
+    glyph.glyphs.verticalLineTripleDashBold;
+
+/// A dashed horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┈". If it's `true`, this is
+/// "-" instead.
+String get horizontalLineQuadrupleDash =>
+    glyph.glyphs.horizontalLineQuadrupleDash;
+
+/// A bold dashed horizontal line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┉". If it's `true`, this is
+/// "-" instead.
+String get horizontalLineQuadrupleDashBold =>
+    glyph.glyphs.horizontalLineQuadrupleDashBold;
+
+/// A dashed vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┊". If it's `true`, this is
+/// "|" instead.
+String get verticalLineQuadrupleDash => glyph.glyphs.verticalLineQuadrupleDash;
+
+/// A bold dashed vertical line that can be used to draw a box.
+///
+/// If [ascii] is `false`, this is "┋". If it's `true`, this is
+/// "|" instead.
+String get verticalLineQuadrupleDashBold =>
+    glyph.glyphs.verticalLineQuadrupleDashBold;
diff --git a/lib/src/generated/unicode_glyph_set.dart b/lib/src/generated/unicode_glyph_set.dart
new file mode 100644
index 0000000..4e54068
--- /dev/null
+++ b/lib/src/generated/unicode_glyph_set.dart
@@ -0,0 +1,322 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Don't modify this file by hand! It's generated by tool/generate.dart.
+
+import 'glyph_set.dart';
+
+/// A [GlyphSet] that includes only Unicode glyphs.
+class UnicodeGlyphSet implements GlyphSet {
+  const UnicodeGlyphSet();
+
+  /// Returns [glyph] if [this] supports Unicode glyphs and [alternative]
+  /// otherwise.
+  String glyphOrAscii(String glyph, String alternative) => glyph;
+
+  /// A bullet point.
+  ///
+  /// Always "•" for [this].
+  String get bullet => "•";
+
+  /// A left-pointing arrow.
+  ///
+  /// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+  /// terminal fonts, and should generally be surrounding by spaces.
+  ///
+  /// Always "←" for [this].
+  String get leftArrow => "←";
+
+  /// A right-pointing arrow.
+  ///
+  /// Note that the Unicode arrow glyphs may overlap with adjacent characters in some
+  /// terminal fonts, and should generally be surrounding by spaces.
+  ///
+  /// Always "→" for [this].
+  String get rightArrow => "→";
+
+  /// An upwards-pointing arrow.
+  ///
+  /// Always "↑" for [this].
+  String get upArrow => "↑";
+
+  /// A downwards-pointing arrow.
+  ///
+  /// Always "↓" for [this].
+  String get downArrow => "↓";
+
+  /// A two-character left-pointing arrow.
+  ///
+  /// Always "◀━" for [this].
+  String get longLeftArrow => "◀━";
+
+  /// A two-character right-pointing arrow.
+  ///
+  /// Always "━▶" for [this].
+  String get longRightArrow => "━▶";
+
+  /// A horizontal line that can be used to draw a box.
+  ///
+  /// Always "─" for [this].
+  String get horizontalLine => "─";
+
+  /// A vertical line that can be used to draw a box.
+  ///
+  /// Always "│" for [this].
+  String get verticalLine => "│";
+
+  /// The upper left-hand corner of a box.
+  ///
+  /// Always "┌" for [this].
+  String get topLeftCorner => "┌";
+
+  /// The upper right-hand corner of a box.
+  ///
+  /// Always "┐" for [this].
+  String get topRightCorner => "┐";
+
+  /// The lower left-hand corner of a box.
+  ///
+  /// Always "└" for [this].
+  String get bottomLeftCorner => "└";
+
+  /// The lower right-hand corner of a box.
+  ///
+  /// Always "┘" for [this].
+  String get bottomRightCorner => "┘";
+
+  /// An intersection of vertical and horizontal box lines.
+  ///
+  /// Always "┼" for [this].
+  String get cross => "┼";
+
+  /// A horizontal box line with a vertical line going up from the middle.
+  ///
+  /// Always "┴" for [this].
+  String get teeUp => "┴";
+
+  /// A horizontal box line with a vertical line going down from the middle.
+  ///
+  /// Always "┬" for [this].
+  String get teeDown => "┬";
+
+  /// A vertical box line with a horizontal line going left from the middle.
+  ///
+  /// Always "┤" for [this].
+  String get teeLeft => "┤";
+
+  /// A vertical box line with a horizontal line going right from the middle.
+  ///
+  /// Always "├" for [this].
+  String get teeRight => "├";
+
+  /// The top half of a vertical box line.
+  ///
+  /// Always "╵" for [this].
+  String get upEnd => "╵";
+
+  /// The bottom half of a vertical box line.
+  ///
+  /// Always "╷" for [this].
+  String get downEnd => "╷";
+
+  /// The left half of a horizontal box line.
+  ///
+  /// Always "╴" for [this].
+  String get leftEnd => "╴";
+
+  /// The right half of a horizontal box line.
+  ///
+  /// Always "╶" for [this].
+  String get rightEnd => "╶";
+
+  /// A bold horizontal line that can be used to draw a box.
+  ///
+  /// Always "━" for [this].
+  String get horizontalLineBold => "━";
+
+  /// A bold vertical line that can be used to draw a box.
+  ///
+  /// Always "┃" for [this].
+  String get verticalLineBold => "┃";
+
+  /// The bold upper left-hand corner of a box.
+  ///
+  /// Always "┏" for [this].
+  String get topLeftCornerBold => "┏";
+
+  /// The bold upper right-hand corner of a box.
+  ///
+  /// Always "┓" for [this].
+  String get topRightCornerBold => "┓";
+
+  /// The bold lower left-hand corner of a box.
+  ///
+  /// Always "┗" for [this].
+  String get bottomLeftCornerBold => "┗";
+
+  /// The bold lower right-hand corner of a box.
+  ///
+  /// Always "┛" for [this].
+  String get bottomRightCornerBold => "┛";
+
+  /// An intersection of bold vertical and horizontal box lines.
+  ///
+  /// Always "╋" for [this].
+  String get crossBold => "╋";
+
+  /// A bold horizontal box line with a vertical line going up from the middle.
+  ///
+  /// Always "┻" for [this].
+  String get teeUpBold => "┻";
+
+  /// A bold horizontal box line with a vertical line going down from the middle.
+  ///
+  /// Always "┳" for [this].
+  String get teeDownBold => "┳";
+
+  /// A bold vertical box line with a horizontal line going left from the middle.
+  ///
+  /// Always "┫" for [this].
+  String get teeLeftBold => "┫";
+
+  /// A bold vertical box line with a horizontal line going right from the middle.
+  ///
+  /// Always "┣" for [this].
+  String get teeRightBold => "┣";
+
+  /// The top half of a bold vertical box line.
+  ///
+  /// Always "╹" for [this].
+  String get upEndBold => "╹";
+
+  /// The bottom half of a bold vertical box line.
+  ///
+  /// Always "╻" for [this].
+  String get downEndBold => "╻";
+
+  /// The left half of a bold horizontal box line.
+  ///
+  /// Always "╸" for [this].
+  String get leftEndBold => "╸";
+
+  /// The right half of a bold horizontal box line.
+  ///
+  /// Always "╺" for [this].
+  String get rightEndBold => "╺";
+
+  /// A double horizontal line that can be used to draw a box.
+  ///
+  /// Always "═" for [this].
+  String get horizontalLineDouble => "═";
+
+  /// A double vertical line that can be used to draw a box.
+  ///
+  /// Always "║" for [this].
+  String get verticalLineDouble => "║";
+
+  /// The double upper left-hand corner of a box.
+  ///
+  /// Always "╔" for [this].
+  String get topLeftCornerDouble => "╔";
+
+  /// The double upper right-hand corner of a box.
+  ///
+  /// Always "╗" for [this].
+  String get topRightCornerDouble => "╗";
+
+  /// The double lower left-hand corner of a box.
+  ///
+  /// Always "╚" for [this].
+  String get bottomLeftCornerDouble => "╚";
+
+  /// The double lower right-hand corner of a box.
+  ///
+  /// Always "╝" for [this].
+  String get bottomRightCornerDouble => "╝";
+
+  /// An intersection of double vertical and horizontal box lines.
+  ///
+  /// Always "╬" for [this].
+  String get crossDouble => "╬";
+
+  /// A double horizontal box line with a vertical line going up from the middle.
+  ///
+  /// Always "╩" for [this].
+  String get teeUpDouble => "╩";
+
+  /// A double horizontal box line with a vertical line going down from the middle.
+  ///
+  /// Always "╦" for [this].
+  String get teeDownDouble => "╦";
+
+  /// A double vertical box line with a horizontal line going left from the middle.
+  ///
+  /// Always "╣" for [this].
+  String get teeLeftDouble => "╣";
+
+  /// A double vertical box line with a horizontal line going right from the middle.
+  ///
+  /// Always "╠" for [this].
+  String get teeRightDouble => "╠";
+
+  /// A dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "╌" for [this].
+  String get horizontalLineDoubleDash => "╌";
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "╍" for [this].
+  String get horizontalLineDoubleDashBold => "╍";
+
+  /// A dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "╎" for [this].
+  String get verticalLineDoubleDash => "╎";
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "╏" for [this].
+  String get verticalLineDoubleDashBold => "╏";
+
+  /// A dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "┄" for [this].
+  String get horizontalLineTripleDash => "┄";
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "┅" for [this].
+  String get horizontalLineTripleDashBold => "┅";
+
+  /// A dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "┆" for [this].
+  String get verticalLineTripleDash => "┆";
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "┇" for [this].
+  String get verticalLineTripleDashBold => "┇";
+
+  /// A dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "┈" for [this].
+  String get horizontalLineQuadrupleDash => "┈";
+
+  /// A bold dashed horizontal line that can be used to draw a box.
+  ///
+  /// Always "┉" for [this].
+  String get horizontalLineQuadrupleDashBold => "┉";
+
+  /// A dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "┊" for [this].
+  String get verticalLineQuadrupleDash => "┊";
+
+  /// A bold dashed vertical line that can be used to draw a box.
+  ///
+  /// Always "┋" for [this].
+  String get verticalLineQuadrupleDashBold => "┋";
+}
diff --git a/lib/term_glyph.dart b/lib/term_glyph.dart
index 8582175..57c762e 100644
--- a/lib/term_glyph.dart
+++ b/lib/term_glyph.dart
@@ -2,11 +2,36 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-export 'src/generated.dart';
+export 'src/generated/glyph_set.dart';
+export 'src/generated/top_level.dart';
 
-import 'src/generated.dart';
+import 'src/generated/ascii_glyph_set.dart';
+import 'src/generated/glyph_set.dart';
+import 'src/generated/unicode_glyph_set.dart';
+
+/// A [GlyphSet] that always returns ASCII glyphs.
+const GlyphSet asciiGlyphs = const AsciiGlyphSet();
+
+/// A [GlyphSet] that always returns Unicode glyphs.
+const GlyphSet unicodeGlyphs = const UnicodeGlyphSet();
+
+/// Returns [asciiGlyphs] if [ascii] is `true` or [unicodeGlyphs] otherwise.
+///
+/// Returns [unicodeGlyphs] by default.
+GlyphSet get glyphs => _glyphs;
+GlyphSet _glyphs = unicodeGlyphs;
+
+/// Whether the glyph getters return plain ASCII, as opposed to Unicode
+/// characters or sequences.
+///
+/// Defaults to `false`.
+bool get ascii => glyphs == asciiGlyphs;
+
+set ascii(bool value) {
+  _glyphs = value ? asciiGlyphs : unicodeGlyphs;
+}
 
 /// Returns [glyph] if Unicode glyph are allowed, and [alternative] if they
 /// aren't.
 String glyphOrAscii(String glyph, String alternative) =>
-    ascii ? alternative : glyph;
+    glyphs.glyphOrAscii(glyph, alternative);
diff --git a/pubspec.yaml b/pubspec.yaml
index 4cbaeb4..29ea7d6 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
 name: term_glyph
-version: 1.0.2-dev
+version: 1.1.0
 
-description: Useful glyphs and Windows-safe equivalents.
+description: Useful Unicode glyphs and ASCII substitutes.
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/term_glyph
 
@@ -11,4 +11,5 @@
 dev_dependencies:
   csv: '>=3.0.0 <5.0.0'
   dart_style: '>=0.2.0 <2.0.0'
+  meta: '>=0.9.0 <2.0.0'
   test: '>=0.12.0 <2.0.0'
diff --git a/test/symbol_test.dart b/test/symbol_test.dart
index e3f94e5..1e665e8 100644
--- a/test/symbol_test.dart
+++ b/test/symbol_test.dart
@@ -12,7 +12,7 @@
       glyph.ascii = false;
     });
 
-    test("glyphs return Unicode versions", () {
+    test("glyph getters return Unicode versions", () {
       expect(glyph.topLeftCorner, equals("┌"));
       expect(glyph.teeUpBold, equals("┻"));
       expect(glyph.longLeftArrow, equals("◀━"));
@@ -21,6 +21,16 @@
     test("glyphOrAscii returns the first argument", () {
       expect(glyph.glyphOrAscii("A", "B"), equals("A"));
     });
+
+    test("glyphs returns unicodeGlyphs", () {
+      expect(glyph.glyphs, equals(glyph.unicodeGlyphs));
+    });
+
+    test("asciiGlyphs still returns ASCII characters", () {
+      expect(glyph.asciiGlyphs.topLeftCorner, equals(","));
+      expect(glyph.asciiGlyphs.teeUpBold, equals("+"));
+      expect(glyph.asciiGlyphs.longLeftArrow, equals("<="));
+    });
   });
 
   group("with ascii = true", () {
@@ -37,5 +47,15 @@
     test("glyphOrAscii returns the second argument", () {
       expect(glyph.glyphOrAscii("A", "B"), equals("B"));
     });
+
+    test("glyphs returns asciiGlyphs", () {
+      expect(glyph.glyphs, equals(glyph.asciiGlyphs));
+    });
+
+    test("unicodeGlyphs still returns Unicode characters", () {
+      expect(glyph.unicodeGlyphs.topLeftCorner, equals("┌"));
+      expect(glyph.unicodeGlyphs.teeUpBold, equals("┻"));
+      expect(glyph.unicodeGlyphs.longLeftArrow, equals("◀━"));
+    });
   });
 }
diff --git a/tool/generate.dart b/tool/generate.dart
index aa05c13..b4b3e43 100644
--- a/tool/generate.dart
+++ b/tool/generate.dart
@@ -5,6 +5,7 @@
 import 'dart:io';
 
 import 'package:csv/csv.dart';
+import 'package:meta/meta.dart';
 
 void main() {
   var csv = new CsvCodec(eol: "\n");
@@ -13,36 +14,130 @@
   // Remove comments and empty lines.
   data.removeWhere((row) => row.length < 3);
 
-  var file = new File("lib/src/generated.dart").openSync(mode: FileMode.write);
-  file.writeStringSync("""
-    // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+  new Directory("lib/src/generated").createSync(recursive: true);
+
+  _writeGlyphSetInterface(data);
+  _writeGlyphSet(data, ascii: false);
+  _writeGlyphSet(data, ascii: true);
+  _writeTopLevel(data);
+
+  var result = Process.runSync(
+      "pub", ["run", "dart_style:format", "-w", "lib/src/generated"]);
+  print(result.stderr);
+  exit(result.exitCode);
+}
+
+/// Writes `lib/src/generated/glyph_set.dart`.
+void _writeGlyphSetInterface(List<List> data) {
+  var file = new File("lib/src/generated/glyph_set.dart")
+      .openSync(mode: FileMode.write);
+  file.writeStringSync(r"""
+    // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
     // for details. All rights reserved. Use of this source code is governed by a
     // BSD-style license that can be found in the LICENSE file.
 
     // Don't modify this file by hand! It's generated by tool/generate.dart.
 
-    /// Whether the glyph getters return plain ASCII, as opposed to Unicode
-    /// characters or sequences.
+    /// A class that provides access to every configurable glyph.
     ///
-    /// Defaults to `false`.
-    bool get ascii => _ascii;
-    var _ascii = false;
-    set ascii(bool value) {
-      _ascii = value;
-      if (value) {
+    /// This is provided as a class so that individual chunks of code can choose
+    /// between [ascii] and [unicode] glyphs. For example:
+    ///
+    /// ```dart
+    /// import 'package:term_glyph/term_glyph.dart' as glyph;
+    ///
+    /// /// Adds a vertical line to the left of [text].
+    /// ///
+    /// /// If [unicode] is `true`, this uses Unicode for the line. If it's
+    /// /// `false`, this uses plain ASCII characters. If it's `null`, it
+    /// /// defaults to [glyph.ascii].
+    /// void addVerticalLine(String text, {bool unicode}) {
+    ///   var glyphs =
+    ///       (unicode ?? !glyph.ascii) ? glyph.unicodeGlyphs : glyph.asciiGlyphs;
+    ///
+    ///   return text
+    ///       .split("\n")
+    ///       .map((line) => "${glyphs.verticalLine} $line")
+    ///       .join("\n");
+    /// }
+    /// ```
+    abstract class GlyphSet {
+      /// Returns [glyph] if [this] supports Unicode glyphs and [alternative]
+      /// otherwise.
+      String glyphOrAscii(String glyph, String alternative);
   """);
 
   for (var glyph in data) {
-    file.writeStringSync("_${glyph[0]} = ${_quote(glyph[2])};");
+    for (var line in glyph[3].split("\n")) {
+      file.writeStringSync("/// $line\n");
+    }
+
+    file.writeStringSync("String get ${glyph[0]};");
   }
 
-  file.writeStringSync("} else {");
+  file.writeStringSync("}");
+  file.closeSync();
+}
 
+/// Writes `lib/src/generated/${prefix.toLowerCase()}_glyph_set.dart`.
+///
+/// If [ascii] is `true`, this writes the ASCII glyph set. Otherwise it writes
+/// the Unicode glyph set.
+void _writeGlyphSet(List<List> data, {@required bool ascii}) {
+  var file = new File(
+          "lib/src/generated/${ascii ? "ascii" : "unicode"}_glyph_set.dart")
+      .openSync(mode: FileMode.write);
+
+  var className = "${ascii ? "Ascii" : "Unicode"}GlyphSet";
+  file.writeStringSync("""
+    // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+    // for details. All rights reserved. Use of this source code is governed by a
+    // BSD-style license that can be found in the LICENSE file.
+
+    // Don't modify this file by hand! It's generated by tool/generate.dart.
+
+    import 'glyph_set.dart';
+
+    /// A [GlyphSet] that includes only ${ascii ? "ASCII" : "Unicode"} glyphs.
+    class $className implements GlyphSet {
+      const $className();
+      /// Returns [glyph] if [this] supports Unicode glyphs and [alternative]
+      /// otherwise.
+      String glyphOrAscii(String glyph, String alternative) =>
+          ${ascii ? "alternative" : "glyph"};
+  """);
+
+  var index = ascii ? 2 : 1;
   for (var glyph in data) {
-    file.writeStringSync("_${glyph[0]} = ${_quote(glyph[1])};");
+    for (var line in glyph[3].split("\n")) {
+      file.writeStringSync("/// $line\n");
+    }
+
+    file.writeStringSync("""
+      ///
+      /// Always ${_quote(glyph[index])} for [this].
+      String get ${glyph[0]} => ${_quote(glyph[index])};
+    """);
   }
 
-  file.writeStringSync("}}");
+  file.writeStringSync("}");
+  file.closeSync();
+}
+
+/// Writes `lib/src/generated/top_level.dart`.
+void _writeTopLevel(List<List> data) {
+  var file = new File("lib/src/generated/top_level.dart")
+      .openSync(mode: FileMode.write);
+
+  file.writeStringSync("""
+    // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+    // for details. All rights reserved. Use of this source code is governed by a
+    // BSD-style license that can be found in the LICENSE file.
+
+    // Don't modify this file by hand! It's generated by tool/generate.dart.
+
+    import '../../term_glyph.dart' as glyph;
+  """);
 
   for (var glyph in data) {
     for (var line in glyph[3].split("\n")) {
@@ -53,15 +148,11 @@
       ///
       /// If [ascii] is `false`, this is "${glyph[1]}". If it's `true`, this is
       /// "${glyph[2]}" instead.
-      String get ${glyph[0]} => _${glyph[0]};
-      var _${glyph[0]} = ${_quote(glyph[1])};
+      String get ${glyph[0]} => glyph.glyphs.${glyph[0]};
     """);
   }
 
-  var result = Process.runSync(
-      "pub", ["run", "dart_style:format", "-w", "lib/src/generated.dart"]);
-  print(result.stderr);
-  exit(result.exitCode);
+  file.closeSync();
 }
 
 String _quote(String input) => input.contains('"') ? "'$input'" : '"$input"';