class_docstr: For `Crystal <http://crystal-lang.org>`_ source code.
  
  .. versionadded:: 2.2
class_docstr_tok: ["For","`","Crystal","<","http",":","\/\/crystal-lang.org",">","`","_","source","code",".","..","versionadded",":",":","2.2"]
code: def gen_crystalstrings_rules():
      def intp_regex_callback(self, match, ctx):
          yield match.start(1), String.Regex, match.group(1)  # begin
          nctx = LexerContext(match.group(3), 0, ["interpolated-regex"])
          for i, t, v in self.get_tokens_unprocessed(context=nctx):
              yield match.start(3) + i, t, v
          yield match.start(4), String.Regex, match.group(
              4
          )  # end[imsx]*
          ctx.pos = match.end()
  
      def intp_string_callback(self, match, ctx):
          yield match.start(1), String.Other, match.group(1)
          nctx = LexerContext(
              match.group(3), 0, ["interpolated-string"]
          )
          for i, t, v in self.get_tokens_unprocessed(context=nctx):
              yield match.start(3) + i, t, v
          yield match.start(4), String.Other, match.group(4)  # end
          ctx.pos = match.end()
  
      states = {}
      states["strings"] = [
          (r"\:@{0,2}[a-zA-Z_]\w*[!?]?", String.Symbol),
          (words(CRYSTAL_OPERATORS, prefix=r"\:@{0,2}"), String.Symbol),
          (r":'(\\\\|\\'|[^'])*'", String.Symbol),
          # This allows arbitrary text after '\ for simplicity
          (r"'(\\\\|\\'|[^']|\\[^'\\]+)'", String.Char),
          (r':"', String.Symbol, "simple-sym"),
          # Crystal doesn't have "symbol:"s but this simplifies function args
          (
              r"([a-zA-Z_]\w*)(:)(?!:)",
              bygroups(String.Symbol, Punctuation),
          ),
          (r'"', String.Double, "simple-string"),
          (r"(?<!\.)`", String.Backtick, "simple-backtick"),
      ]
  
      # double-quoted string and symbol
      for name, ttype, end in (
          ("string", String.Double, '"'),
          ("sym", String.Symbol, '"'),
          ("backtick", String.Backtick, "`"),
      ):
          states["simple-" + name] = [
              include(
                  "string-escaped"
                  if name == "sym"
                  else "string-intp-escaped"
              ),
              (r"[^\\%s#]+" % end, ttype),
              (r"[\\#]", ttype),
              (end, ttype, "#pop"),
          ]
  
      # braced quoted strings
      for lbrace, rbrace, bracecc, name in (
          ("\\{", "\\}", "{}", "cb"),
          ("\\[", "\\]", "\\[\\]", "sb"),
          ("\\(", "\\)", "()", "pa"),
          ("<", ">", "<>", "ab"),
      ):
          states[name + "-intp-string"] = [
              (r"\\[" + lbrace + "]", String.Other),
              (lbrace, String.Other, "#push"),
              (rbrace, String.Other, "#pop"),
              include("string-intp-escaped"),
              (r"[\\#" + bracecc + "]", String.Other),
              (r"[^\\#" + bracecc + "]+", String.Other),
          ]
          states["strings"].append(
              (r"%" + lbrace, String.Other, name + "-intp-string")
          )
          states[name + "-string"] = [
              (r"\\[\\" + bracecc + "]", String.Other),
              (lbrace, String.Other, "#push"),
              (rbrace, String.Other, "#pop"),
              (r"[\\#" + bracecc + "]", String.Other),
              (r"[^\\#" + bracecc + "]+", String.Other),
          ]
          # http://crystal-lang.org/docs/syntax_and_semantics/literals/array.html
          states["strings"].append(
              (r"%[wi]" + lbrace, String.Other, name + "-string")
          )
          states[name + "-regex"] = [
              (r"\\[\\" + bracecc + "]", String.Regex),
              (lbrace, String.Regex, "#push"),
              (rbrace + "[imsx]*", String.Regex, "#pop"),
              include("string-intp"),
              (r"[\\#" + bracecc + "]", String.Regex),
              (r"[^\\#" + bracecc + "]+", String.Regex),
          ]
          states["strings"].append(
              (r"%r" + lbrace, String.Regex, name + "-regex")
          )
  
      # these must come after %<brace>!
      states["strings"] += [
          # %r regex
          (
              r"(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[imsx]*)",
              intp_regex_callback,
          ),
          # regular fancy strings with qsw
          (
              r"(%[wi]([\W_]))((?:\\\2|(?!\2).)*)(\2)",
              intp_string_callback,
          ),
          # special forms of fancy strings after operators or
          # in method calls with braces
          (
              r"(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)",
              bygroups(Text, String.Other, None),
          ),
          # and because of fixed width lookbehinds the whole thing a
          # second time for line startings...
          (
              r"^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)",
              bygroups(Text, String.Other, None),
          ),
          # all regular fancy strings without qsw
          (
              r"(%([\[{(<]))((?:\\\2|(?!\2).)*)(\2)",
              intp_string_callback,
          ),
      ]
  
      return states
  
imports: import re
  from pygments.lexer import ExtendedRegexLexer, include, bygroups, default, LexerContext, words
  from pygments.token import Text, Comment, Operator, Keyword, Name, String, Number, Punctuation, Error
label_desc: Use image node_id 2 for calling the CrystalLexer obj's underlying member method code with example usage: obj.gen_crystalstrings_rules() and returns: states