code: function (scanner, inAttribute) {
    // look for `&` followed by alphanumeric
    if (! peekMatcher(scanner, getPossibleNamedEntityStart))
      return null;
  
    var matcher = getNamedEntityByFirstChar[scanner.rest().charAt(1)];
    var entity = null;
    if (matcher)
      entity = peekMatcher(scanner, matcher);
  
    if (entity) {
      if (entity.slice(-1) !== ';') {
        // Certain character references with no semi are an error, like `&lt`.
        // In attribute values, however, this is not fatal if the next character
        // is alphanumeric.
        //
        // This rule affects href attributes, for example, deeming "/?foo=bar&ltc=abc"
        // to be ok but "/?foo=bar&lt=abc" to not be.
        if (inAttribute && ALPHANUMERIC.test(scanner.rest().charAt(entity.length)))
          return null;
        scanner.fatal("Character reference requires semicolon: " + entity);
      } else {
        scanner.pos += entity.length;
        return entity;
      }
    } else {
      // we couldn't match any real entity, so see if this is a bad entity
      // or something we can overlook.
      var badEntity = peekMatcher(scanner, getApparentNamedEntity);
      if (badEntity)
        scanner.fatal("Invalid character reference: " + badEntity);
      // `&aaaa` is ok with no semicolon
      return null;
    }
  }
docs: Returns a string like "&amp;" or a falsy value if no match.  Fails fatally if something looks like a named entity but isn't.