src/lib/Parser.js
/**
  Consumes a reference if possible.

  This differs from `consumeContentReference()` in that a consumed reference
  will be returned rather than added to the document.

  @returns {string|false}
    Parsed reference value, or `false` if nothing was consumed (to distinguish
    from a reference that resolves to an empty string).

  @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Reference
  */
Consumes a reference if possible.
This differs from `consumeContentReference()` in that a consumed reference
will be returned rather than added to the document.
Consumes a reference if possible . This differs from ` consumeContentReference () ` in that a consumed reference will be returned rather than added to the document .
consumeReference() {
    let { scanner } = this;
    if (scanner.peek() !== '&') {
      return false;
    }
    scanner.advance();
    let ref = scanner.consumeMatchFn(syntax.isReferenceChar);
    if (scanner.consume() !== ';') {
      this.error('Unterminated reference (a reference must end with `;`)');
    }
    let parsedValue;
    if (ref[0] === '#') {
      let codePoint = ref[1] === 'x'
        ? parseInt(ref.slice(2), 16) 
        : parseInt(ref.slice(1), 10); 
      if (isNaN(codePoint)) {
        this.error('Invalid character reference');
      }
      parsedValue = String.fromCodePoint(codePoint);
      if (!syntax.isXmlChar(parsedValue)) {
        this.error('Character reference resolves to an invalid character');
      }
    } else {
      parsedValue = syntax.predefinedEntities[ref];
      if (parsedValue === undefined) {
        let {
          ignoreUndefinedEntities,
          resolveUndefinedEntity,
        } = this.options;
        let wrappedRef = `&${ref};`; 
        if (resolveUndefinedEntity) {
          let resolvedValue = resolveUndefinedEntity(wrappedRef);
          if (resolvedValue !== null && resolvedValue !== undefined) {
            let type = typeof resolvedValue;
            if (type !== 'string') {
              throw new TypeError(`\`resolveUndefinedEntity()\` must return a string, \`null\`, or \`undefined\`, but returned a value of type ${type}`);
            }
            return resolvedValue;
          }
        }
        if (ignoreUndefinedEntities) {
          return wrappedRef;
        }
        scanner.reset(-wrappedRef.length);
        this.error(`Named entity isn't defined: ${wrappedRef}`);
      }
    }
    return parsedValue;
  }
consumeReference ( ) { let { scanner } = this ; if ( scanner . peek ( ) !== '&' ) { return false ; } scanner . advance ( ) ; let ref = scanner . consumeMatchFn ( syntax . isReferenceChar ) ; if ( scanner . consume ( ) !== ';' ) { this . error ( 'Unterminated reference (a reference must end with `;`)' ) ; } let parsedValue ; if ( ref [ 0 ] === '#' ) { let codePoint = ref [ 1 ] === 'x' ? parseInt ( ref . slice ( 2 ) , 16 ) : parseInt ( ref . slice ( 1 ) , 10 ) ; if ( isNaN ( codePoint ) ) { this . error ( 'Invalid character reference' ) ; } parsedValue = String . fromCodePoint ( codePoint ) ; if ( ! syntax . isXmlChar ( parsedValue ) ) { this . error ( 'Character reference resolves to an invalid character' ) ; } } else { parsedValue = syntax . predefinedEntities [ ref ] ; if ( parsedValue === undefined ) { let { ignoreUndefinedEntities , resolveUndefinedEntity , } = this . options ; let wrappedRef = ` ${ ref } ` ; if ( resolveUndefinedEntity ) { let resolvedValue = resolveUndefinedEntity ( wrappedRef ) ; if ( resolvedValue !== null && resolvedValue !== undefined ) { let type = typeof resolvedValue ; if ( type !== 'string' ) { throw new TypeError ( ` \` \` \` \` \` \` ${ type } ` ) ; } return resolvedValue ; } } if ( ignoreUndefinedEntities ) { return wrappedRef ; } scanner . reset ( - wrappedRef . length ) ; this . error ( ` ${ wrappedRef } ` ) ; } } return parsedValue ; }
Consumes a reference if possible.
Consumes a reference if possible .
// This is a character reference. // Hex codepoint. // Decimal codepoint. // This is an entity reference. // for backcompat with <= 2.x