webmisc.py 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. """
  2. pygments.lexers.webmisc
  3. ~~~~~~~~~~~~~~~~~~~~~~~
  4. Lexers for misc. web stuff.
  5. :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
  6. :license: BSD, see LICENSE for details.
  7. """
  8. import re
  9. from pygments.lexer import RegexLexer, ExtendedRegexLexer, include, bygroups, \
  10. default, using
  11. from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
  12. Number, Punctuation, Literal, Whitespace
  13. from pygments.lexers.css import _indentation, _starts_block
  14. from pygments.lexers.html import HtmlLexer
  15. from pygments.lexers.javascript import JavascriptLexer
  16. from pygments.lexers.ruby import RubyLexer
  17. __all__ = ['DuelLexer', 'SlimLexer', 'XQueryLexer', 'QmlLexer', 'CirruLexer']
  18. class DuelLexer(RegexLexer):
  19. """
  20. Lexer for Duel Views Engine (formerly JBST) markup with JavaScript code blocks.
  21. .. versionadded:: 1.4
  22. """
  23. name = 'Duel'
  24. url = 'http://duelengine.org/'
  25. aliases = ['duel', 'jbst', 'jsonml+bst']
  26. filenames = ['*.duel', '*.jbst']
  27. mimetypes = ['text/x-duel', 'text/x-jbst']
  28. flags = re.DOTALL
  29. tokens = {
  30. 'root': [
  31. (r'(<%[@=#!:]?)(.*?)(%>)',
  32. bygroups(Name.Tag, using(JavascriptLexer), Name.Tag)),
  33. (r'(<%\$)(.*?)(:)(.*?)(%>)',
  34. bygroups(Name.Tag, Name.Function, Punctuation, String, Name.Tag)),
  35. (r'(<%--)(.*?)(--%>)',
  36. bygroups(Name.Tag, Comment.Multiline, Name.Tag)),
  37. (r'(<script.*?>)(.*?)(</script>)',
  38. bygroups(using(HtmlLexer),
  39. using(JavascriptLexer), using(HtmlLexer))),
  40. (r'(.+?)(?=<)', using(HtmlLexer)),
  41. (r'.+', using(HtmlLexer)),
  42. ],
  43. }
  44. class XQueryLexer(ExtendedRegexLexer):
  45. """
  46. An XQuery lexer, parsing a stream and outputting the tokens needed to
  47. highlight xquery code.
  48. .. versionadded:: 1.4
  49. """
  50. name = 'XQuery'
  51. url = 'https://www.w3.org/XML/Query/'
  52. aliases = ['xquery', 'xqy', 'xq', 'xql', 'xqm']
  53. filenames = ['*.xqy', '*.xquery', '*.xq', '*.xql', '*.xqm']
  54. mimetypes = ['text/xquery', 'application/xquery']
  55. xquery_parse_state = []
  56. # FIX UNICODE LATER
  57. # ncnamestartchar = (
  58. # r"[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|"
  59. # r"[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|"
  60. # r"[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]|"
  61. # r"[\u10000-\uEFFFF]"
  62. # )
  63. ncnamestartchar = r"(?:[A-Z]|_|[a-z])"
  64. # FIX UNICODE LATER
  65. # ncnamechar = ncnamestartchar + (r"|-|\.|[0-9]|\u00B7|[\u0300-\u036F]|"
  66. # r"[\u203F-\u2040]")
  67. ncnamechar = r"(?:" + ncnamestartchar + r"|-|\.|[0-9])"
  68. ncname = "(?:%s+%s*)" % (ncnamestartchar, ncnamechar)
  69. pitarget_namestartchar = r"(?:[A-KN-WYZ]|_|:|[a-kn-wyz])"
  70. pitarget_namechar = r"(?:" + pitarget_namestartchar + r"|-|\.|[0-9])"
  71. pitarget = "%s+%s*" % (pitarget_namestartchar, pitarget_namechar)
  72. prefixedname = "%s:%s" % (ncname, ncname)
  73. unprefixedname = ncname
  74. qname = "(?:%s|%s)" % (prefixedname, unprefixedname)
  75. entityref = r'(?:&(?:lt|gt|amp|quot|apos|nbsp);)'
  76. charref = r'(?:&#[0-9]+;|&#x[0-9a-fA-F]+;)'
  77. stringdouble = r'(?:"(?:' + entityref + r'|' + charref + r'|""|[^&"])*")'
  78. stringsingle = r"(?:'(?:" + entityref + r"|" + charref + r"|''|[^&'])*')"
  79. # FIX UNICODE LATER
  80. # elementcontentchar = (r'\t|\r|\n|[\u0020-\u0025]|[\u0028-\u003b]|'
  81. # r'[\u003d-\u007a]|\u007c|[\u007e-\u007F]')
  82. elementcontentchar = r'[A-Za-z]|\s|\d|[!"#$%()*+,\-./:;=?@\[\\\]^_\'`|~]'
  83. # quotattrcontentchar = (r'\t|\r|\n|[\u0020-\u0021]|[\u0023-\u0025]|'
  84. # r'[\u0027-\u003b]|[\u003d-\u007a]|\u007c|[\u007e-\u007F]')
  85. quotattrcontentchar = r'[A-Za-z]|\s|\d|[!#$%()*+,\-./:;=?@\[\\\]^_\'`|~]'
  86. # aposattrcontentchar = (r'\t|\r|\n|[\u0020-\u0025]|[\u0028-\u003b]|'
  87. # r'[\u003d-\u007a]|\u007c|[\u007e-\u007F]')
  88. aposattrcontentchar = r'[A-Za-z]|\s|\d|[!"#$%()*+,\-./:;=?@\[\\\]^_`|~]'
  89. # CHAR elements - fix the above elementcontentchar, quotattrcontentchar,
  90. # aposattrcontentchar
  91. # x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
  92. flags = re.DOTALL | re.MULTILINE
  93. def punctuation_root_callback(lexer, match, ctx):
  94. yield match.start(), Punctuation, match.group(1)
  95. # transition to root always - don't pop off stack
  96. ctx.stack = ['root']
  97. ctx.pos = match.end()
  98. def operator_root_callback(lexer, match, ctx):
  99. yield match.start(), Operator, match.group(1)
  100. # transition to root always - don't pop off stack
  101. ctx.stack = ['root']
  102. ctx.pos = match.end()
  103. def popstate_tag_callback(lexer, match, ctx):
  104. yield match.start(), Name.Tag, match.group(1)
  105. if lexer.xquery_parse_state:
  106. ctx.stack.append(lexer.xquery_parse_state.pop())
  107. ctx.pos = match.end()
  108. def popstate_xmlcomment_callback(lexer, match, ctx):
  109. yield match.start(), String.Doc, match.group(1)
  110. ctx.stack.append(lexer.xquery_parse_state.pop())
  111. ctx.pos = match.end()
  112. def popstate_kindtest_callback(lexer, match, ctx):
  113. yield match.start(), Punctuation, match.group(1)
  114. next_state = lexer.xquery_parse_state.pop()
  115. if next_state == 'occurrenceindicator':
  116. if re.match("[?*+]+", match.group(2)):
  117. yield match.start(), Punctuation, match.group(2)
  118. ctx.stack.append('operator')
  119. ctx.pos = match.end()
  120. else:
  121. ctx.stack.append('operator')
  122. ctx.pos = match.end(1)
  123. else:
  124. ctx.stack.append(next_state)
  125. ctx.pos = match.end(1)
  126. def popstate_callback(lexer, match, ctx):
  127. yield match.start(), Punctuation, match.group(1)
  128. # if we have run out of our state stack, pop whatever is on the pygments
  129. # state stack
  130. if len(lexer.xquery_parse_state) == 0:
  131. ctx.stack.pop()
  132. if not ctx.stack:
  133. # make sure we have at least the root state on invalid inputs
  134. ctx.stack = ['root']
  135. elif len(ctx.stack) > 1:
  136. ctx.stack.append(lexer.xquery_parse_state.pop())
  137. else:
  138. # i don't know if i'll need this, but in case, default back to root
  139. ctx.stack = ['root']
  140. ctx.pos = match.end()
  141. def pushstate_element_content_starttag_callback(lexer, match, ctx):
  142. yield match.start(), Name.Tag, match.group(1)
  143. lexer.xquery_parse_state.append('element_content')
  144. ctx.stack.append('start_tag')
  145. ctx.pos = match.end()
  146. def pushstate_cdata_section_callback(lexer, match, ctx):
  147. yield match.start(), String.Doc, match.group(1)
  148. ctx.stack.append('cdata_section')
  149. lexer.xquery_parse_state.append(ctx.state.pop)
  150. ctx.pos = match.end()
  151. def pushstate_starttag_callback(lexer, match, ctx):
  152. yield match.start(), Name.Tag, match.group(1)
  153. lexer.xquery_parse_state.append(ctx.state.pop)
  154. ctx.stack.append('start_tag')
  155. ctx.pos = match.end()
  156. def pushstate_operator_order_callback(lexer, match, ctx):
  157. yield match.start(), Keyword, match.group(1)
  158. yield match.start(), Whitespace, match.group(2)
  159. yield match.start(), Punctuation, match.group(3)
  160. ctx.stack = ['root']
  161. lexer.xquery_parse_state.append('operator')
  162. ctx.pos = match.end()
  163. def pushstate_operator_map_callback(lexer, match, ctx):
  164. yield match.start(), Keyword, match.group(1)
  165. yield match.start(), Whitespace, match.group(2)
  166. yield match.start(), Punctuation, match.group(3)
  167. ctx.stack = ['root']
  168. lexer.xquery_parse_state.append('operator')
  169. ctx.pos = match.end()
  170. def pushstate_operator_root_validate(lexer, match, ctx):
  171. yield match.start(), Keyword, match.group(1)
  172. yield match.start(), Whitespace, match.group(2)
  173. yield match.start(), Punctuation, match.group(3)
  174. ctx.stack = ['root']
  175. lexer.xquery_parse_state.append('operator')
  176. ctx.pos = match.end()
  177. def pushstate_operator_root_validate_withmode(lexer, match, ctx):
  178. yield match.start(), Keyword, match.group(1)
  179. yield match.start(), Whitespace, match.group(2)
  180. yield match.start(), Keyword, match.group(3)
  181. ctx.stack = ['root']
  182. lexer.xquery_parse_state.append('operator')
  183. ctx.pos = match.end()
  184. def pushstate_operator_processing_instruction_callback(lexer, match, ctx):
  185. yield match.start(), String.Doc, match.group(1)
  186. ctx.stack.append('processing_instruction')
  187. lexer.xquery_parse_state.append('operator')
  188. ctx.pos = match.end()
  189. def pushstate_element_content_processing_instruction_callback(lexer, match, ctx):
  190. yield match.start(), String.Doc, match.group(1)
  191. ctx.stack.append('processing_instruction')
  192. lexer.xquery_parse_state.append('element_content')
  193. ctx.pos = match.end()
  194. def pushstate_element_content_cdata_section_callback(lexer, match, ctx):
  195. yield match.start(), String.Doc, match.group(1)
  196. ctx.stack.append('cdata_section')
  197. lexer.xquery_parse_state.append('element_content')
  198. ctx.pos = match.end()
  199. def pushstate_operator_cdata_section_callback(lexer, match, ctx):
  200. yield match.start(), String.Doc, match.group(1)
  201. ctx.stack.append('cdata_section')
  202. lexer.xquery_parse_state.append('operator')
  203. ctx.pos = match.end()
  204. def pushstate_element_content_xmlcomment_callback(lexer, match, ctx):
  205. yield match.start(), String.Doc, match.group(1)
  206. ctx.stack.append('xml_comment')
  207. lexer.xquery_parse_state.append('element_content')
  208. ctx.pos = match.end()
  209. def pushstate_operator_xmlcomment_callback(lexer, match, ctx):
  210. yield match.start(), String.Doc, match.group(1)
  211. ctx.stack.append('xml_comment')
  212. lexer.xquery_parse_state.append('operator')
  213. ctx.pos = match.end()
  214. def pushstate_kindtest_callback(lexer, match, ctx):
  215. yield match.start(), Keyword, match.group(1)
  216. yield match.start(), Whitespace, match.group(2)
  217. yield match.start(), Punctuation, match.group(3)
  218. lexer.xquery_parse_state.append('kindtest')
  219. ctx.stack.append('kindtest')
  220. ctx.pos = match.end()
  221. def pushstate_operator_kindtestforpi_callback(lexer, match, ctx):
  222. yield match.start(), Keyword, match.group(1)
  223. yield match.start(), Whitespace, match.group(2)
  224. yield match.start(), Punctuation, match.group(3)
  225. lexer.xquery_parse_state.append('operator')
  226. ctx.stack.append('kindtestforpi')
  227. ctx.pos = match.end()
  228. def pushstate_operator_kindtest_callback(lexer, match, ctx):
  229. yield match.start(), Keyword, match.group(1)
  230. yield match.start(), Whitespace, match.group(2)
  231. yield match.start(), Punctuation, match.group(3)
  232. lexer.xquery_parse_state.append('operator')
  233. ctx.stack.append('kindtest')
  234. ctx.pos = match.end()
  235. def pushstate_occurrenceindicator_kindtest_callback(lexer, match, ctx):
  236. yield match.start(), Name.Tag, match.group(1)
  237. yield match.start(), Whitespace, match.group(2)
  238. yield match.start(), Punctuation, match.group(3)
  239. lexer.xquery_parse_state.append('occurrenceindicator')
  240. ctx.stack.append('kindtest')
  241. ctx.pos = match.end()
  242. def pushstate_operator_starttag_callback(lexer, match, ctx):
  243. yield match.start(), Name.Tag, match.group(1)
  244. lexer.xquery_parse_state.append('operator')
  245. ctx.stack.append('start_tag')
  246. ctx.pos = match.end()
  247. def pushstate_operator_root_callback(lexer, match, ctx):
  248. yield match.start(), Punctuation, match.group(1)
  249. lexer.xquery_parse_state.append('operator')
  250. ctx.stack = ['root']
  251. ctx.pos = match.end()
  252. def pushstate_operator_root_construct_callback(lexer, match, ctx):
  253. yield match.start(), Keyword, match.group(1)
  254. yield match.start(), Whitespace, match.group(2)
  255. yield match.start(), Punctuation, match.group(3)
  256. lexer.xquery_parse_state.append('operator')
  257. ctx.stack = ['root']
  258. ctx.pos = match.end()
  259. def pushstate_root_callback(lexer, match, ctx):
  260. yield match.start(), Punctuation, match.group(1)
  261. cur_state = ctx.stack.pop()
  262. lexer.xquery_parse_state.append(cur_state)
  263. ctx.stack = ['root']
  264. ctx.pos = match.end()
  265. def pushstate_operator_attribute_callback(lexer, match, ctx):
  266. yield match.start(), Name.Attribute, match.group(1)
  267. ctx.stack.append('operator')
  268. ctx.pos = match.end()
  269. tokens = {
  270. 'comment': [
  271. # xquery comments
  272. (r'[^:()]+', Comment),
  273. (r'\(:', Comment, '#push'),
  274. (r':\)', Comment, '#pop'),
  275. (r'[:()]', Comment),
  276. ],
  277. 'whitespace': [
  278. (r'\s+', Whitespace),
  279. ],
  280. 'operator': [
  281. include('whitespace'),
  282. (r'(\})', popstate_callback),
  283. (r'\(:', Comment, 'comment'),
  284. (r'(\{)', pushstate_root_callback),
  285. (r'then|else|external|at|div|except', Keyword, 'root'),
  286. (r'order by', Keyword, 'root'),
  287. (r'group by', Keyword, 'root'),
  288. (r'is|mod|order\s+by|stable\s+order\s+by', Keyword, 'root'),
  289. (r'and|or', Operator.Word, 'root'),
  290. (r'(eq|ge|gt|le|lt|ne|idiv|intersect|in)(?=\b)',
  291. Operator.Word, 'root'),
  292. (r'return|satisfies|to|union|where|count|preserve\s+strip',
  293. Keyword, 'root'),
  294. (r'(>=|>>|>|<=|<<|<|-|\*|!=|\+|\|\||\||:=|=|!)',
  295. operator_root_callback),
  296. (r'(::|:|;|\[|//|/|,)',
  297. punctuation_root_callback),
  298. (r'(castable|cast)(\s+)(as)\b',
  299. bygroups(Keyword, Whitespace, Keyword), 'singletype'),
  300. (r'(instance)(\s+)(of)\b',
  301. bygroups(Keyword, Whitespace, Keyword), 'itemtype'),
  302. (r'(treat)(\s+)(as)\b',
  303. bygroups(Keyword, Whitespace, Keyword), 'itemtype'),
  304. (r'(case)(\s+)(' + stringdouble + ')',
  305. bygroups(Keyword, Whitespace, String.Double), 'itemtype'),
  306. (r'(case)(\s+)(' + stringsingle + ')',
  307. bygroups(Keyword, Whitespace, String.Single), 'itemtype'),
  308. (r'(case|as)\b', Keyword, 'itemtype'),
  309. (r'(\))(\s*)(as)',
  310. bygroups(Punctuation, Whitespace, Keyword), 'itemtype'),
  311. (r'\$', Name.Variable, 'varname'),
  312. (r'(for|let|previous|next)(\s+)(\$)',
  313. bygroups(Keyword, Whitespace, Name.Variable), 'varname'),
  314. (r'(for)(\s+)(tumbling|sliding)(\s+)(window)(\s+)(\$)',
  315. bygroups(Keyword, Whitespace, Keyword, Whitespace, Keyword,
  316. Whitespace, Name.Variable),
  317. 'varname'),
  318. # (r'\)|\?|\]', Punctuation, '#push'),
  319. (r'\)|\?|\]', Punctuation),
  320. (r'(empty)(\s+)(greatest|least)',
  321. bygroups(Keyword, Whitespace, Keyword)),
  322. (r'ascending|descending|default', Keyword, '#push'),
  323. (r'(allowing)(\s+)(empty)',
  324. bygroups(Keyword, Whitespace, Keyword)),
  325. (r'external', Keyword),
  326. (r'(start|when|end)', Keyword, 'root'),
  327. (r'(only)(\s+)(end)', bygroups(Keyword, Whitespace, Keyword),
  328. 'root'),
  329. (r'collation', Keyword, 'uritooperator'),
  330. # eXist specific XQUF
  331. (r'(into|following|preceding|with)', Keyword, 'root'),
  332. # support for current context on rhs of Simple Map Operator
  333. (r'\.', Operator),
  334. # finally catch all string literals and stay in operator state
  335. (stringdouble, String.Double),
  336. (stringsingle, String.Single),
  337. (r'(catch)(\s*)', bygroups(Keyword, Whitespace), 'root'),
  338. ],
  339. 'uritooperator': [
  340. (stringdouble, String.Double, '#pop'),
  341. (stringsingle, String.Single, '#pop'),
  342. ],
  343. 'namespacedecl': [
  344. include('whitespace'),
  345. (r'\(:', Comment, 'comment'),
  346. (r'(at)(\s+)('+stringdouble+')',
  347. bygroups(Keyword, Whitespace, String.Double)),
  348. (r"(at)(\s+)("+stringsingle+')',
  349. bygroups(Keyword, Whitespace, String.Single)),
  350. (stringdouble, String.Double),
  351. (stringsingle, String.Single),
  352. (r',', Punctuation),
  353. (r'=', Operator),
  354. (r';', Punctuation, 'root'),
  355. (ncname, Name.Namespace),
  356. ],
  357. 'namespacekeyword': [
  358. include('whitespace'),
  359. (r'\(:', Comment, 'comment'),
  360. (stringdouble, String.Double, 'namespacedecl'),
  361. (stringsingle, String.Single, 'namespacedecl'),
  362. (r'inherit|no-inherit', Keyword, 'root'),
  363. (r'namespace', Keyword, 'namespacedecl'),
  364. (r'(default)(\s+)(element)', bygroups(Keyword, Text, Keyword)),
  365. (r'preserve|no-preserve', Keyword),
  366. (r',', Punctuation),
  367. ],
  368. 'annotationname': [
  369. (r'\(:', Comment, 'comment'),
  370. (qname, Name.Decorator),
  371. (r'(\()(' + stringdouble + ')', bygroups(Punctuation, String.Double)),
  372. (r'(\()(' + stringsingle + ')', bygroups(Punctuation, String.Single)),
  373. (r'(\,)(\s+)(' + stringdouble + ')',
  374. bygroups(Punctuation, Text, String.Double)),
  375. (r'(\,)(\s+)(' + stringsingle + ')',
  376. bygroups(Punctuation, Text, String.Single)),
  377. (r'\)', Punctuation),
  378. (r'(\s+)(\%)', bygroups(Text, Name.Decorator), 'annotationname'),
  379. (r'(\s+)(variable)(\s+)(\$)',
  380. bygroups(Text, Keyword.Declaration, Text, Name.Variable), 'varname'),
  381. (r'(\s+)(function)(\s+)',
  382. bygroups(Text, Keyword.Declaration, Text), 'root')
  383. ],
  384. 'varname': [
  385. (r'\(:', Comment, 'comment'),
  386. (r'(' + qname + r')(\()?', bygroups(Name, Punctuation), 'operator'),
  387. ],
  388. 'singletype': [
  389. include('whitespace'),
  390. (r'\(:', Comment, 'comment'),
  391. (ncname + r'(:\*)', Name.Variable, 'operator'),
  392. (qname, Name.Variable, 'operator'),
  393. ],
  394. 'itemtype': [
  395. include('whitespace'),
  396. (r'\(:', Comment, 'comment'),
  397. (r'\$', Name.Variable, 'varname'),
  398. (r'(void)(\s*)(\()(\s*)(\))',
  399. bygroups(Keyword, Text, Punctuation, Text, Punctuation), 'operator'),
  400. (r'(element|attribute|schema-element|schema-attribute|comment|text|'
  401. r'node|binary|document-node|empty-sequence)(\s*)(\()',
  402. pushstate_occurrenceindicator_kindtest_callback),
  403. # Marklogic specific type?
  404. (r'(processing-instruction)(\s*)(\()',
  405. bygroups(Keyword, Text, Punctuation),
  406. ('occurrenceindicator', 'kindtestforpi')),
  407. (r'(item)(\s*)(\()(\s*)(\))(?=[*+?])',
  408. bygroups(Keyword, Text, Punctuation, Text, Punctuation),
  409. 'occurrenceindicator'),
  410. (r'(\(\#)(\s*)', bygroups(Punctuation, Text), 'pragma'),
  411. (r';', Punctuation, '#pop'),
  412. (r'then|else', Keyword, '#pop'),
  413. (r'(at)(\s+)(' + stringdouble + ')',
  414. bygroups(Keyword, Text, String.Double), 'namespacedecl'),
  415. (r'(at)(\s+)(' + stringsingle + ')',
  416. bygroups(Keyword, Text, String.Single), 'namespacedecl'),
  417. (r'except|intersect|in|is|return|satisfies|to|union|where|count',
  418. Keyword, 'root'),
  419. (r'and|div|eq|ge|gt|le|lt|ne|idiv|mod|or', Operator.Word, 'root'),
  420. (r':=|=|,|>=|>>|>|\[|\(|<=|<<|<|-|!=|\|\||\|', Operator, 'root'),
  421. (r'external|at', Keyword, 'root'),
  422. (r'(stable)(\s+)(order)(\s+)(by)',
  423. bygroups(Keyword, Text, Keyword, Text, Keyword), 'root'),
  424. (r'(castable|cast)(\s+)(as)',
  425. bygroups(Keyword, Text, Keyword), 'singletype'),
  426. (r'(treat)(\s+)(as)', bygroups(Keyword, Text, Keyword)),
  427. (r'(instance)(\s+)(of)', bygroups(Keyword, Text, Keyword)),
  428. (r'(case)(\s+)(' + stringdouble + ')',
  429. bygroups(Keyword, Text, String.Double), 'itemtype'),
  430. (r'(case)(\s+)(' + stringsingle + ')',
  431. bygroups(Keyword, Text, String.Single), 'itemtype'),
  432. (r'case|as', Keyword, 'itemtype'),
  433. (r'(\))(\s*)(as)', bygroups(Operator, Text, Keyword), 'itemtype'),
  434. (ncname + r':\*', Keyword.Type, 'operator'),
  435. (r'(function|map|array)(\()', bygroups(Keyword.Type, Punctuation)),
  436. (qname, Keyword.Type, 'occurrenceindicator'),
  437. ],
  438. 'kindtest': [
  439. (r'\(:', Comment, 'comment'),
  440. (r'\{', Punctuation, 'root'),
  441. (r'(\))([*+?]?)', popstate_kindtest_callback),
  442. (r'\*', Name, 'closekindtest'),
  443. (qname, Name, 'closekindtest'),
  444. (r'(element|schema-element)(\s*)(\()', pushstate_kindtest_callback),
  445. ],
  446. 'kindtestforpi': [
  447. (r'\(:', Comment, 'comment'),
  448. (r'\)', Punctuation, '#pop'),
  449. (ncname, Name.Variable),
  450. (stringdouble, String.Double),
  451. (stringsingle, String.Single),
  452. ],
  453. 'closekindtest': [
  454. (r'\(:', Comment, 'comment'),
  455. (r'(\))', popstate_callback),
  456. (r',', Punctuation),
  457. (r'(\{)', pushstate_operator_root_callback),
  458. (r'\?', Punctuation),
  459. ],
  460. 'xml_comment': [
  461. (r'(-->)', popstate_xmlcomment_callback),
  462. (r'[^-]{1,2}', Literal),
  463. (r'\t|\r|\n|[\u0020-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF]',
  464. Literal),
  465. ],
  466. 'processing_instruction': [
  467. (r'\s+', Text, 'processing_instruction_content'),
  468. (r'\?>', String.Doc, '#pop'),
  469. (pitarget, Name),
  470. ],
  471. 'processing_instruction_content': [
  472. (r'\?>', String.Doc, '#pop'),
  473. (r'\t|\r|\n|[\u0020-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF]',
  474. Literal),
  475. ],
  476. 'cdata_section': [
  477. (r']]>', String.Doc, '#pop'),
  478. (r'\t|\r|\n|[\u0020-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF]',
  479. Literal),
  480. ],
  481. 'start_tag': [
  482. include('whitespace'),
  483. (r'(/>)', popstate_tag_callback),
  484. (r'>', Name.Tag, 'element_content'),
  485. (r'"', Punctuation, 'quot_attribute_content'),
  486. (r"'", Punctuation, 'apos_attribute_content'),
  487. (r'=', Operator),
  488. (qname, Name.Tag),
  489. ],
  490. 'quot_attribute_content': [
  491. (r'"', Punctuation, 'start_tag'),
  492. (r'(\{)', pushstate_root_callback),
  493. (r'""', Name.Attribute),
  494. (quotattrcontentchar, Name.Attribute),
  495. (entityref, Name.Attribute),
  496. (charref, Name.Attribute),
  497. (r'\{\{|\}\}', Name.Attribute),
  498. ],
  499. 'apos_attribute_content': [
  500. (r"'", Punctuation, 'start_tag'),
  501. (r'\{', Punctuation, 'root'),
  502. (r"''", Name.Attribute),
  503. (aposattrcontentchar, Name.Attribute),
  504. (entityref, Name.Attribute),
  505. (charref, Name.Attribute),
  506. (r'\{\{|\}\}', Name.Attribute),
  507. ],
  508. 'element_content': [
  509. (r'</', Name.Tag, 'end_tag'),
  510. (r'(\{)', pushstate_root_callback),
  511. (r'(<!--)', pushstate_element_content_xmlcomment_callback),
  512. (r'(<\?)', pushstate_element_content_processing_instruction_callback),
  513. (r'(<!\[CDATA\[)', pushstate_element_content_cdata_section_callback),
  514. (r'(<)', pushstate_element_content_starttag_callback),
  515. (elementcontentchar, Literal),
  516. (entityref, Literal),
  517. (charref, Literal),
  518. (r'\{\{|\}\}', Literal),
  519. ],
  520. 'end_tag': [
  521. include('whitespace'),
  522. (r'(>)', popstate_tag_callback),
  523. (qname, Name.Tag),
  524. ],
  525. 'xmlspace_decl': [
  526. include('whitespace'),
  527. (r'\(:', Comment, 'comment'),
  528. (r'preserve|strip', Keyword, '#pop'),
  529. ],
  530. 'declareordering': [
  531. (r'\(:', Comment, 'comment'),
  532. include('whitespace'),
  533. (r'ordered|unordered', Keyword, '#pop'),
  534. ],
  535. 'xqueryversion': [
  536. include('whitespace'),
  537. (r'\(:', Comment, 'comment'),
  538. (stringdouble, String.Double),
  539. (stringsingle, String.Single),
  540. (r'encoding', Keyword),
  541. (r';', Punctuation, '#pop'),
  542. ],
  543. 'pragma': [
  544. (qname, Name.Variable, 'pragmacontents'),
  545. ],
  546. 'pragmacontents': [
  547. (r'#\)', Punctuation, 'operator'),
  548. (r'\t|\r|\n|[\u0020-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF]',
  549. Literal),
  550. (r'(\s+)', Whitespace),
  551. ],
  552. 'occurrenceindicator': [
  553. include('whitespace'),
  554. (r'\(:', Comment, 'comment'),
  555. (r'\*|\?|\+', Operator, 'operator'),
  556. (r':=', Operator, 'root'),
  557. default('operator'),
  558. ],
  559. 'option': [
  560. include('whitespace'),
  561. (qname, Name.Variable, '#pop'),
  562. ],
  563. 'qname_braren': [
  564. include('whitespace'),
  565. (r'(\{)', pushstate_operator_root_callback),
  566. (r'(\()', Punctuation, 'root'),
  567. ],
  568. 'element_qname': [
  569. (qname, Name.Variable, 'root'),
  570. ],
  571. 'attribute_qname': [
  572. (qname, Name.Variable, 'root'),
  573. ],
  574. 'root': [
  575. include('whitespace'),
  576. (r'\(:', Comment, 'comment'),
  577. # handle operator state
  578. # order on numbers matters - handle most complex first
  579. (r'\d+(\.\d*)?[eE][+-]?\d+', Number.Float, 'operator'),
  580. (r'(\.\d+)[eE][+-]?\d+', Number.Float, 'operator'),
  581. (r'(\.\d+|\d+\.\d*)', Number.Float, 'operator'),
  582. (r'(\d+)', Number.Integer, 'operator'),
  583. (r'(\.\.|\.|\))', Punctuation, 'operator'),
  584. (r'(declare)(\s+)(construction)',
  585. bygroups(Keyword.Declaration, Text, Keyword.Declaration), 'operator'),
  586. (r'(declare)(\s+)(default)(\s+)(order)',
  587. bygroups(Keyword.Declaration, Text, Keyword.Declaration, Text, Keyword.Declaration), 'operator'),
  588. (r'(declare)(\s+)(context)(\s+)(item)',
  589. bygroups(Keyword.Declaration, Text, Keyword.Declaration, Text, Keyword.Declaration), 'operator'),
  590. (ncname + r':\*', Name, 'operator'),
  591. (r'\*:'+ncname, Name.Tag, 'operator'),
  592. (r'\*', Name.Tag, 'operator'),
  593. (stringdouble, String.Double, 'operator'),
  594. (stringsingle, String.Single, 'operator'),
  595. (r'(\}|\])', popstate_callback),
  596. # NAMESPACE DECL
  597. (r'(declare)(\s+)(default)(\s+)(collation)',
  598. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration,
  599. Whitespace, Keyword.Declaration)),
  600. (r'(module|declare)(\s+)(namespace)',
  601. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration),
  602. 'namespacedecl'),
  603. (r'(declare)(\s+)(base-uri)',
  604. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration),
  605. 'namespacedecl'),
  606. # NAMESPACE KEYWORD
  607. (r'(declare)(\s+)(default)(\s+)(element|function)',
  608. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration,
  609. Whitespace, Keyword.Declaration),
  610. 'namespacekeyword'),
  611. (r'(import)(\s+)(schema|module)',
  612. bygroups(Keyword.Pseudo, Whitespace, Keyword.Pseudo),
  613. 'namespacekeyword'),
  614. (r'(declare)(\s+)(copy-namespaces)',
  615. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration),
  616. 'namespacekeyword'),
  617. # VARNAMEs
  618. (r'(for|let|some|every)(\s+)(\$)',
  619. bygroups(Keyword, Whitespace, Name.Variable), 'varname'),
  620. (r'(for)(\s+)(tumbling|sliding)(\s+)(window)(\s+)(\$)',
  621. bygroups(Keyword, Whitespace, Keyword, Whitespace, Keyword,
  622. Whitespace, Name.Variable),
  623. 'varname'),
  624. (r'\$', Name.Variable, 'varname'),
  625. (r'(declare)(\s+)(variable)(\s+)(\$)',
  626. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration,
  627. Whitespace, Name.Variable),
  628. 'varname'),
  629. # ANNOTATED GLOBAL VARIABLES AND FUNCTIONS
  630. (r'(declare)(\s+)(\%)', bygroups(Keyword.Declaration, Whitespace,
  631. Name.Decorator),
  632. 'annotationname'),
  633. # ITEMTYPE
  634. (r'(\))(\s+)(as)', bygroups(Operator, Whitespace, Keyword),
  635. 'itemtype'),
  636. (r'(element|attribute|schema-element|schema-attribute|comment|'
  637. r'text|node|document-node|empty-sequence)(\s+)(\()',
  638. pushstate_operator_kindtest_callback),
  639. (r'(processing-instruction)(\s+)(\()',
  640. pushstate_operator_kindtestforpi_callback),
  641. (r'(<!--)', pushstate_operator_xmlcomment_callback),
  642. (r'(<\?)', pushstate_operator_processing_instruction_callback),
  643. (r'(<!\[CDATA\[)', pushstate_operator_cdata_section_callback),
  644. # (r'</', Name.Tag, 'end_tag'),
  645. (r'(<)', pushstate_operator_starttag_callback),
  646. (r'(declare)(\s+)(boundary-space)',
  647. bygroups(Keyword.Declaration, Text, Keyword.Declaration), 'xmlspace_decl'),
  648. (r'(validate)(\s+)(lax|strict)',
  649. pushstate_operator_root_validate_withmode),
  650. (r'(validate)(\s*)(\{)', pushstate_operator_root_validate),
  651. (r'(typeswitch)(\s*)(\()', bygroups(Keyword, Whitespace,
  652. Punctuation)),
  653. (r'(switch)(\s*)(\()', bygroups(Keyword, Whitespace, Punctuation)),
  654. (r'(element|attribute|namespace)(\s*)(\{)',
  655. pushstate_operator_root_construct_callback),
  656. (r'(document|text|processing-instruction|comment)(\s*)(\{)',
  657. pushstate_operator_root_construct_callback),
  658. # ATTRIBUTE
  659. (r'(attribute)(\s+)(?=' + qname + r')',
  660. bygroups(Keyword, Whitespace), 'attribute_qname'),
  661. # ELEMENT
  662. (r'(element)(\s+)(?=' + qname + r')',
  663. bygroups(Keyword, Whitespace), 'element_qname'),
  664. # PROCESSING_INSTRUCTION
  665. (r'(processing-instruction|namespace)(\s+)(' + ncname + r')(\s*)(\{)',
  666. bygroups(Keyword, Whitespace, Name.Variable, Whitespace,
  667. Punctuation),
  668. 'operator'),
  669. (r'(declare|define)(\s+)(function)',
  670. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration)),
  671. (r'(\{|\[)', pushstate_operator_root_callback),
  672. (r'(unordered|ordered)(\s*)(\{)',
  673. pushstate_operator_order_callback),
  674. (r'(map|array)(\s*)(\{)',
  675. pushstate_operator_map_callback),
  676. (r'(declare)(\s+)(ordering)',
  677. bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration),
  678. 'declareordering'),
  679. (r'(xquery)(\s+)(version)',
  680. bygroups(Keyword.Pseudo, Whitespace, Keyword.Pseudo),
  681. 'xqueryversion'),
  682. (r'(\(#)(\s*)', bygroups(Punctuation, Whitespace), 'pragma'),
  683. # sometimes return can occur in root state
  684. (r'return', Keyword),
  685. (r'(declare)(\s+)(option)', bygroups(Keyword.Declaration,
  686. Whitespace,
  687. Keyword.Declaration),
  688. 'option'),
  689. # URI LITERALS - single and double quoted
  690. (r'(at)(\s+)('+stringdouble+')', String.Double, 'namespacedecl'),
  691. (r'(at)(\s+)('+stringsingle+')', String.Single, 'namespacedecl'),
  692. (r'(ancestor-or-self|ancestor|attribute|child|descendant-or-self)(::)',
  693. bygroups(Keyword, Punctuation)),
  694. (r'(descendant|following-sibling|following|parent|preceding-sibling'
  695. r'|preceding|self)(::)', bygroups(Keyword, Punctuation)),
  696. (r'(if)(\s*)(\()', bygroups(Keyword, Whitespace, Punctuation)),
  697. (r'then|else', Keyword),
  698. # eXist specific XQUF
  699. (r'(update)(\s*)(insert|delete|replace|value|rename)',
  700. bygroups(Keyword, Whitespace, Keyword)),
  701. (r'(into|following|preceding|with)', Keyword),
  702. # Marklogic specific
  703. (r'(try)(\s*)', bygroups(Keyword, Whitespace), 'root'),
  704. (r'(catch)(\s*)(\()(\$)',
  705. bygroups(Keyword, Whitespace, Punctuation, Name.Variable),
  706. 'varname'),
  707. (r'(@'+qname+')', Name.Attribute, 'operator'),
  708. (r'(@'+ncname+')', Name.Attribute, 'operator'),
  709. (r'@\*:'+ncname, Name.Attribute, 'operator'),
  710. (r'@\*', Name.Attribute, 'operator'),
  711. (r'(@)', Name.Attribute, 'operator'),
  712. (r'//|/|\+|-|;|,|\(|\)', Punctuation),
  713. # STANDALONE QNAMES
  714. (qname + r'(?=\s*\{)', Name.Tag, 'qname_braren'),
  715. (qname + r'(?=\s*\([^:])', Name.Function, 'qname_braren'),
  716. (r'(' + qname + ')(#)([0-9]+)', bygroups(Name.Function, Keyword.Type, Number.Integer)),
  717. (qname, Name.Tag, 'operator'),
  718. ]
  719. }
  720. class QmlLexer(RegexLexer):
  721. """
  722. For QML files.
  723. .. versionadded:: 1.6
  724. """
  725. # QML is based on javascript, so much of this is taken from the
  726. # JavascriptLexer above.
  727. name = 'QML'
  728. url = 'https://doc.qt.io/qt-6/qmlapplications.html'
  729. aliases = ['qml', 'qbs']
  730. filenames = ['*.qml', '*.qbs']
  731. mimetypes = ['application/x-qml', 'application/x-qt.qbs+qml']
  732. # pasted from JavascriptLexer, with some additions
  733. flags = re.DOTALL | re.MULTILINE
  734. tokens = {
  735. 'commentsandwhitespace': [
  736. (r'\s+', Text),
  737. (r'<!--', Comment),
  738. (r'//.*?\n', Comment.Single),
  739. (r'/\*.*?\*/', Comment.Multiline)
  740. ],
  741. 'slashstartsregex': [
  742. include('commentsandwhitespace'),
  743. (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
  744. r'([gim]+\b|\B)', String.Regex, '#pop'),
  745. (r'(?=/)', Text, ('#pop', 'badregex')),
  746. default('#pop')
  747. ],
  748. 'badregex': [
  749. (r'\n', Text, '#pop')
  750. ],
  751. 'root': [
  752. (r'^(?=\s|/|<!--)', Text, 'slashstartsregex'),
  753. include('commentsandwhitespace'),
  754. (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|'
  755. r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'),
  756. (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
  757. (r'[})\].]', Punctuation),
  758. # QML insertions
  759. (r'\bid\s*:\s*[A-Za-z][\w.]*', Keyword.Declaration,
  760. 'slashstartsregex'),
  761. (r'\b[A-Za-z][\w.]*\s*:', Keyword, 'slashstartsregex'),
  762. # the rest from JavascriptLexer
  763. (r'(for|in|while|do|break|return|continue|switch|case|default|if|else|'
  764. r'throw|try|catch|finally|new|delete|typeof|instanceof|void|'
  765. r'this)\b', Keyword, 'slashstartsregex'),
  766. (r'(var|let|with|function)\b', Keyword.Declaration, 'slashstartsregex'),
  767. (r'(abstract|boolean|byte|char|class|const|debugger|double|enum|export|'
  768. r'extends|final|float|goto|implements|import|int|interface|long|native|'
  769. r'package|private|protected|public|short|static|super|synchronized|throws|'
  770. r'transient|volatile)\b', Keyword.Reserved),
  771. (r'(true|false|null|NaN|Infinity|undefined)\b', Keyword.Constant),
  772. (r'(Array|Boolean|Date|Error|Function|Math|netscape|'
  773. r'Number|Object|Packages|RegExp|String|sun|decodeURI|'
  774. r'decodeURIComponent|encodeURI|encodeURIComponent|'
  775. r'Error|eval|isFinite|isNaN|parseFloat|parseInt|document|this|'
  776. r'window)\b', Name.Builtin),
  777. (r'[$a-zA-Z_]\w*', Name.Other),
  778. (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
  779. (r'0x[0-9a-fA-F]+', Number.Hex),
  780. (r'[0-9]+', Number.Integer),
  781. (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
  782. (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
  783. ]
  784. }
  785. class CirruLexer(RegexLexer):
  786. r"""
  787. * using ``()`` for expressions, but restricted in a same line
  788. * using ``""`` for strings, with ``\`` for escaping chars
  789. * using ``$`` as folding operator
  790. * using ``,`` as unfolding operator
  791. * using indentations for nested blocks
  792. .. versionadded:: 2.0
  793. """
  794. name = 'Cirru'
  795. url = 'http://cirru.org/'
  796. aliases = ['cirru']
  797. filenames = ['*.cirru']
  798. mimetypes = ['text/x-cirru']
  799. flags = re.MULTILINE
  800. tokens = {
  801. 'string': [
  802. (r'[^"\\\n]+', String),
  803. (r'\\', String.Escape, 'escape'),
  804. (r'"', String, '#pop'),
  805. ],
  806. 'escape': [
  807. (r'.', String.Escape, '#pop'),
  808. ],
  809. 'function': [
  810. (r'\,', Operator, '#pop'),
  811. (r'[^\s"()]+', Name.Function, '#pop'),
  812. (r'\)', Operator, '#pop'),
  813. (r'(?=\n)', Text, '#pop'),
  814. (r'\(', Operator, '#push'),
  815. (r'"', String, ('#pop', 'string')),
  816. (r'[ ]+', Text.Whitespace),
  817. ],
  818. 'line': [
  819. (r'(?<!\w)\$(?!\w)', Operator, 'function'),
  820. (r'\(', Operator, 'function'),
  821. (r'\)', Operator),
  822. (r'\n', Text, '#pop'),
  823. (r'"', String, 'string'),
  824. (r'[ ]+', Text.Whitespace),
  825. (r'[+-]?[\d.]+\b', Number),
  826. (r'[^\s"()]+', Name.Variable)
  827. ],
  828. 'root': [
  829. (r'^\n+', Text.Whitespace),
  830. default(('line', 'function')),
  831. ]
  832. }
  833. class SlimLexer(ExtendedRegexLexer):
  834. """
  835. For Slim markup.
  836. .. versionadded:: 2.0
  837. """
  838. name = 'Slim'
  839. aliases = ['slim']
  840. filenames = ['*.slim']
  841. mimetypes = ['text/x-slim']
  842. flags = re.IGNORECASE
  843. _dot = r'(?: \|\n(?=.* \|)|.)'
  844. tokens = {
  845. 'root': [
  846. (r'[ \t]*\n', Text),
  847. (r'[ \t]*', _indentation),
  848. ],
  849. 'css': [
  850. (r'\.[\w:-]+', Name.Class, 'tag'),
  851. (r'\#[\w:-]+', Name.Function, 'tag'),
  852. ],
  853. 'eval-or-plain': [
  854. (r'([ \t]*==?)(.*\n)',
  855. bygroups(Punctuation, using(RubyLexer)),
  856. 'root'),
  857. (r'[ \t]+[\w:-]+(?==)', Name.Attribute, 'html-attributes'),
  858. default('plain'),
  859. ],
  860. 'content': [
  861. include('css'),
  862. (r'[\w:-]+:[ \t]*\n', Text, 'plain'),
  863. (r'(-)(.*\n)',
  864. bygroups(Punctuation, using(RubyLexer)),
  865. '#pop'),
  866. (r'\|' + _dot + r'*\n', _starts_block(Text, 'plain'), '#pop'),
  867. (r'/' + _dot + r'*\n', _starts_block(Comment.Preproc, 'slim-comment-block'), '#pop'),
  868. (r'[\w:-]+', Name.Tag, 'tag'),
  869. include('eval-or-plain'),
  870. ],
  871. 'tag': [
  872. include('css'),
  873. (r'[<>]{1,2}(?=[ \t=])', Punctuation),
  874. (r'[ \t]+\n', Punctuation, '#pop:2'),
  875. include('eval-or-plain'),
  876. ],
  877. 'plain': [
  878. (r'([^#\n]|#[^{\n]|(\\\\)*\\#\{)+', Text),
  879. (r'(#\{)(.*?)(\})',
  880. bygroups(String.Interpol, using(RubyLexer), String.Interpol)),
  881. (r'\n', Text, 'root'),
  882. ],
  883. 'html-attributes': [
  884. (r'=', Punctuation),
  885. (r'"[^"]+"', using(RubyLexer), 'tag'),
  886. (r'\'[^\']+\'', using(RubyLexer), 'tag'),
  887. (r'\w+', Text, 'tag'),
  888. ],
  889. 'slim-comment-block': [
  890. (_dot + '+', Comment.Preproc),
  891. (r'\n', Text, 'root'),
  892. ],
  893. }