const syntax = { } ; syntax . Char = regex `
  (?:
    [
      \t
      \n
      \r
      \x20-\uD7FF
      \uE000-\uFFFD
    ]
    |
    [\uD800-\uDBFF][\uDC00-\uDFFF]
  )
` ; syntax . CharData = regex `
  [^<&]+
` ; syntax . NameStartChar = regex `
  (?:
    [
      :
      A-Z
      _
      a-z
      \xC0-\xD6
      \xD8-\xF6
      \xF8-\u02FF
      \u0370-\u037D
      \u037F-\u1FFF
      \u200C-\u200D
      \u2070-\u218F
      \u2C00-\u2FEF
      \u3001-\uD7FF
      \uF900-\uFDCF
      \uFDF0-\uFFFD
    ]
    |
    [\uD800-\uDB7F][\uDC00-\uDFFF]
  )
` ; syntax . NameChar = regex `
  (?:
    ${ syntax . NameStartChar }
    |
    [
      .
      0-9
      \xB7
      \u0300-\u036F
      \u203F-\u2040
      -
    ]
  )
` ; syntax . Name = regex `
  ${ syntax . NameStartChar }
  (?:${ syntax . NameChar })*
` ; syntax . Reference = regex `
  &\S+?;
` ; syntax . S = regex `
  [\x20\t\r\n]+
` ; syntax . Eq = regex `
  (?:${ syntax . S })?
  =
  (?:${ syntax . S })?
` ; syntax . AttributeName = regex `
  (?:
    ${ syntax . NameStartChar }
    (?:${ syntax . NameChar })*
    |
    \[
    ${ syntax . NameStartChar }
    (?:${ syntax . NameChar })*
    \]
    |
    \(
    ${ syntax . NameStartChar }
    (?:${ syntax . NameChar })*
    \)
  )
` ; syntax . Attribute = regex `
  ${ syntax . AttributeName }
  (?:${ syntax . Eq })*
  (?:
    "(?:
      [^"] | ${ syntax . Reference }
    )*"
    |
    '(?:
      [^'] | ${ syntax . Reference }
    )*'
  )*
` ; syntax . EventAttribute = regex `
\(
  // group 1
  (
    ${ syntax . NameStartChar }
    (?:${ syntax . NameChar })*
  )
\)` ; syntax . BoundAttribute = regex `
\[
  // group 1
  (
    ${ syntax . NameStartChar }
    (?:${ syntax . NameChar })*
  )
\]` ; syntax . Pipes = regex `[^"\|]+|("[^"]*")` ; syntax . PipeArgs = regex `[^":]+|("[^"]*")` ; syntax . CDSect = regex `
  <!\[CDATA\[
    // Group 1: CData text content (optional)
    (
      (?:${ syntax . Char })*?
    )
  \]\]>
` ; syntax . EmptyElemTag = regex `
  <
    // Group 1: Element name
    (${ syntax . Name })
    // Group 2: Attributes (optional)
    (
      (?:
        ${ syntax . S }
        ${ syntax . Attribute }
      )*
    )
    (?:${ syntax . S })?
  />
` ; syntax . ETag = regex `
  </
    // Group 1: End tag name
    (${ syntax . Name })
    (?:${ syntax . S })?
  >
` ; syntax . STag = regex `
  <
    // Group 1: Start tag name
    (${ syntax . Name })
    // Group 2: Attributes (optional)
    (
      (?:
        ${ syntax . S }
        ${ syntax . Attribute }
      )*
    )
    (?:${ syntax . S })?
  >
` ; syntax . CharOnly = regex `
  ^(?:${ syntax . Char })*$
` ; syntax . Comment = regex `
  <!--
    // Group 1: Comment text (optional)
    (
      (?:
        (?!-) ${ syntax . Char }
        | - (?!-) ${ syntax . Char }
      )*
    )
  -->
` ; syntax . doctypedecl = regex `
  <!DOCTYPE
    ${ syntax . S }
    [^[>]*
    (?:
      \[ [\s\S]+? \]
      (?:${ syntax . S })?
    )?
  >
` ; syntax . PI = regex `
  <\?
    // Group 1: PITarget
    (
      ${ syntax . Name }
    )
    (?:
      ${ syntax . S }
      (?:${ syntax . Char })*?
    )?
  \?>
` ; syntax . XMLDecl = regex `
  <\?xml
    ${ syntax . S }
    [\s\S]+?
  \?>
` ; syntax . Anchored = { } ; syntax . Global = { } ; Object . keys ( syntax ) . forEach ( name => { if ( name !== 'Anchored' && name !== 'CharOnly' && name !== 'Global' ) { let pattern = syntax [ name ] ; syntax . Anchored [ name ] = new RegExp ( '^' + pattern . source ) ; syntax . Global [ name ] = new RegExp ( pattern . source , 'g' ) ; } } ) ; function regex ( strings , ... embeddedPatterns ) { let { length , raw } = strings ; let lastIndex = length - 1 ; let pattern = '' ; for ( let i = 0 ; i < length ; ++ i ) { pattern += raw [ i ] . replace ( /(^|[^\\])\/\/.*$/gm , '$1' ) . replace ( /\s+/g , '' ) ; if ( i < lastIndex ) { pattern += embeddedPatterns [ i ] . source ; } } return new RegExp ( pattern ) ; } export = syntax ;