anchor.diff:        });
       }
   
  -    if(showEnds) lines = lines.map((line) => '$line\$');
  +    // Show non-printing characters.
  +    if(showEnds)        lines = lines.map((line) => '$line\$');
  +    if(showTabs)        lines = lines.map((str) => str.replaceAll('\t', '^I'));
  +    if(showNonprinting) lines = lines.map(showNonprintables);
   
  -    if(showTabs) lines = lines.map((str) => str.replaceAll('\t', '^I'));
  -
  -    // TODO: Show non-printing characters.
  -    // See http://docstore.mik.ua/orelly/unix3/upt/ch12_04.htm
  -    if(showNonprinting) {}
  -
  +    // Print lines.
       return lines.forEach(print);
     });
   }
  
positive.code: import 'dart:async';
  import 'dart:convert';
  
  import 'package:unscripted/unscripted.dart';
  import 'package:quiver/async.dart';
  import 'package:quiver/iterables.dart';
  import 'package:quiver/strings.dart';
  
  main(arguments) => sketch(cat).execute(arguments);
  
  @Command(help: 'Concatenate FILE(s), or standard input, to standard output.')
  @ArgExample('f - g', help: "Output f's contents, then standard input, then g's contents.")
  @ArgExample('', help: 'Copy standard input to standard output.')
  /// A dart implementation of the unix utility [cat][cat_wiki].
  /// [cat_wiki]: http://en.wikipedia.org/wiki/Cat_(Unix)
  cat(
      List<Input> files,
      {@Flag(abbr: 'n', help: 'number all output lines')
  
negative.code:     return !squeeze;
    });
  }
  
  // See http://docstore.mik.ua/orelly/unix3/upt/ch12_04.htm
  // Note: This is likely buggy and slow.
  String showNonprintables(String line) {
    String convertNonprintable(int char) {
      isControl(int char) => char <= 037 || char == 0177;
      var buffer = new StringBuffer();
      if (char >= 0200) {
        char &= 0177;
        buffer.write('M-');
      }
      if (isControl(char)) {
        buffer.write('^');
        if (char == 0177) {
          buffer.write('?');
        } else {
          buffer.writeCharCode(char + '@'.codeUnitAt(0));
        }
      } else {
        buffer.writeCharCode(char);
      }
      return buffer.toString();
    }
  
    var re = new RegExp(r'[\x00-\x08\x0A-\x1F\x7F]|[^\x00-\x7F]');
    return line.replaceAllMapped(re, (match) => convertNonprintable(match.input.codeUnitAt(0)));
  }
  