Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pygments/lexers/ul4.py: 91%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

55 statements  

1""" 

2 pygments.lexers.ul4 

3 ~~~~~~~~~~~~~~~~~~~ 

4 

5 Lexer for the UL4 templating language. 

6 

7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. 

8 :license: BSD, see LICENSE for details. 

9""" 

10 

11import re 

12 

13from pygments.lexer import RegexLexer, DelegatingLexer, bygroups, words, include 

14from pygments.token import Comment, Text, Keyword, String, Number, Literal, \ 

15 Name, Other, Operator 

16from pygments.lexers.web import HtmlLexer, XmlLexer, CssLexer, JavascriptLexer 

17from pygments.lexers.python import PythonLexer 

18 

19__all__ = ['UL4Lexer', 'HTMLUL4Lexer', 'XMLUL4Lexer', 'CSSUL4Lexer', 

20 'JavascriptUL4Lexer', 'PythonUL4Lexer'] 

21 

22 

23class UL4Lexer(RegexLexer): 

24 """ 

25 Generic lexer for UL4. 

26 """ 

27 

28 flags = re.MULTILINE | re.DOTALL 

29 

30 name = 'UL4' 

31 aliases = ['ul4'] 

32 filenames = ['*.ul4'] 

33 url = 'https://python.livinglogic.de/UL4.html' 

34 version_added = '2.12' 

35 

36 tokens = { 

37 "root": [ 

38 ( 

39 # Template header without name: 

40 # ``<?ul4?>`` 

41 r"(<\?)(\s*)(ul4)(\s*)(\?>)", 

42 bygroups(Comment.Preproc, Text.Whitespace, Keyword, 

43 Text.Whitespace, Comment.Preproc), 

44 ), 

45 ( 

46 # Template header with name (potentially followed by the signature): 

47 # ``<?ul4 foo(bar=42)?>`` 

48 r"(<\?)(\s*)(ul4)(\s*)([a-zA-Z_][a-zA-Z_0-9]*)?", 

49 bygroups(Comment.Preproc, Text.Whitespace, Keyword, 

50 Text.Whitespace, Name.Function), 

51 "ul4", # Switch to "expression" mode 

52 ), 

53 ( 

54 # Comment: 

55 # ``<?note?>...<?end note?>`` 

56 r"<\?\s*note\s*\?>", 

57 Comment, 

58 "note", # Switch to "note" mode 

59 ), 

60 ( 

61 # Comment: 

62 # ``<?note foobar?>`` 

63 r"<\?\s*note\s.*?\?>", 

64 Comment, 

65 ), 

66 ( 

67 # Template documentation: 

68 # ``<?doc?>...<?end doc?>`` 

69 r"<\?\s*doc\s*\?>", 

70 String.Doc, 

71 "doc", 

72 ), 

73 ( 

74 # Template documentation: 

75 # ``<?doc foobar?>`` 

76 r"<\?\s*doc\s.*?\?>", 

77 String.Doc, 

78 ), 

79 ( 

80 # ``<?ignore?>`` tag for commenting out code: 

81 # ``<?ignore?>...<?end ignore?>`` 

82 r"<\?\s*ignore\s*\?>", 

83 Comment, 

84 "ignore", # Switch to "ignore" mode 

85 ), 

86 ( 

87 # ``<?def?>`` tag for defining local templates 

88 # ``<?def foo(bar=42)?>...<?end def?>`` 

89 r"(<\?)(\s*)(def)(\s*)([a-zA-Z_][a-zA-Z_0-9]*)?", 

90 bygroups(Comment.Preproc, Text.Whitespace, Keyword, 

91 Text.Whitespace, Name.Function), 

92 "ul4", # Switch to "expression" mode 

93 ), 

94 ( 

95 # The rest of the supported tags 

96 r"(<\?)(\s*)(printx|print|for|if|elif|else|while|code|renderblocks?|render)\b", 

97 bygroups(Comment.Preproc, Text.Whitespace, Keyword), 

98 "ul4", # Switch to "expression" mode 

99 ), 

100 ( 

101 # ``<?end?>`` tag for ending ``<?def?>``, ``<?for?>``, 

102 # ``<?if?>``, ``<?while?>``, ``<?renderblock?>`` and 

103 # ``<?renderblocks?>`` blocks. 

104 r"(<\?)(\s*)(end)\b", 

105 bygroups(Comment.Preproc, Text.Whitespace, Keyword), 

106 "end", # Switch to "end tag" mode 

107 ), 

108 ( 

109 # ``<?whitespace?>`` tag for configuring whitespace handlng 

110 r"(<\?)(\s*)(whitespace)\b", 

111 bygroups(Comment.Preproc, Text.Whitespace, Keyword), 

112 "whitespace", # Switch to "whitespace" mode 

113 ), 

114 # Plain text 

115 (r"[^<]+", Other), 

116 (r"<", Other), 

117 ], 

118 # Ignore mode ignores everything upto the matching ``<?end ignore?>`` tag 

119 "ignore": [ 

120 # Nested ``<?ignore?>`` tag 

121 (r"<\?\s*ignore\s*\?>", Comment, "#push"), 

122 # ``<?end ignore?>`` tag 

123 (r"<\?\s*end\s+ignore\s*\?>", Comment, "#pop"), 

124 # Everything else 

125 (r"[^<]+", Comment), 

126 (r".", Comment), 

127 ], 

128 # Note mode ignores everything upto the matching ``<?end note?>`` tag 

129 "note": [ 

130 # Nested ``<?note?>`` tag 

131 (r"<\?\s*note\s*\?>", Comment, "#push"), 

132 # ``<?end note?>`` tag 

133 (r"<\?\s*end\s+note\s*\?>", Comment, "#pop"), 

134 # Everything else 

135 (r"[^<]+", Comment), 

136 (r".", Comment), 

137 ], 

138 # Doc mode ignores everything upto the matching ``<?end doc?>`` tag 

139 "doc": [ 

140 # Nested ``<?doc?>`` tag 

141 (r"<\?\s*doc\s*\?>", String.Doc, "#push"), 

142 # ``<?end doc?>`` tag 

143 (r"<\?\s*end\s+doc\s*\?>", String.Doc, "#pop"), 

144 # Everything else 

145 (r"[^<]+", String.Doc), 

146 (r".", String.Doc), 

147 ], 

148 # UL4 expressions 

149 "ul4": [ 

150 # End the tag 

151 (r"\?>", Comment.Preproc, "#pop"), 

152 # Start triple quoted string constant 

153 ("'''", String, "string13"), 

154 ('"""', String, "string23"), 

155 # Start single quoted string constant 

156 ("'", String, "string1"), 

157 ('"', String, "string2"), 

158 # Floating point number 

159 (r"\d+\.\d*([eE][+-]?\d+)?", Number.Float), 

160 (r"\.\d+([eE][+-]?\d+)?", Number.Float), 

161 (r"\d+[eE][+-]?\d+", Number.Float), 

162 # Binary integer: ``0b101010`` 

163 (r"0[bB][01]+", Number.Bin), 

164 # Octal integer: ``0o52`` 

165 (r"0[oO][0-7]+", Number.Oct), 

166 # Hexadecimal integer: ``0x2a`` 

167 (r"0[xX][0-9a-fA-F]+", Number.Hex), 

168 # Date or datetime: ``@(2000-02-29)``/``@(2000-02-29T12:34:56.987654)`` 

169 (r"@\(\d\d\d\d-\d\d-\d\d(T(\d\d:\d\d(:\d\d(\.\d{6})?)?)?)?\)", Literal.Date), 

170 # Color: ``#fff``, ``#fff8f0`` etc. 

171 (r"#[0-9a-fA-F]{8}", Literal.Color), 

172 (r"#[0-9a-fA-F]{6}", Literal.Color), 

173 (r"#[0-9a-fA-F]{3,4}", Literal.Color), 

174 # Decimal integer: ``42`` 

175 (r"\d+", Number.Integer), 

176 # Operators 

177 (r"//|==|!=|>=|<=|<<|>>|\+=|-=|\*=|/=|//=|<<=|>>=|&=|\|=|^=|=|[\[\]{},:*/().~%&|<>^+-]", Operator), 

178 # Keywords 

179 (words(("for", "in", "if", "else", "not", "is", "and", "or"), suffix=r"\b"), Keyword), 

180 # Builtin constants 

181 (words(("None", "False", "True"), suffix=r"\b"), Keyword.Constant), 

182 # Variable names 

183 (r"[a-zA-Z_][a-zA-Z0-9_]*", Name), 

184 # Whitespace 

185 (r"\s+", Text.Whitespace), 

186 ], 

187 # ``<?end ...?>`` tag for closing the last open block 

188 "end": [ 

189 (r"\?>", Comment.Preproc, "#pop"), 

190 (words(("for", "if", "def", "while", "renderblock", "renderblocks"), suffix=r"\b"), Keyword), 

191 (r"\s+", Text), 

192 ], 

193 # Content of the ``<?whitespace ...?>`` tag: 

194 # ``keep``, ``strip`` or ``smart`` 

195 "whitespace": [ 

196 (r"\?>", Comment.Preproc, "#pop"), 

197 (words(("keep", "strip", "smart"), suffix=r"\b"), Comment.Preproc), 

198 (r"\s+", Text.Whitespace), 

199 ], 

200 # Inside a string constant 

201 "stringescapes": [ 

202 (r"""\\[\\'"abtnfr]""", String.Escape), 

203 (r"\\x[0-9a-fA-F]{2}", String.Escape), 

204 (r"\\u[0-9a-fA-F]{4}", String.Escape), 

205 (r"\\U[0-9a-fA-F]{8}", String.Escape), 

206 ], 

207 # Inside a triple quoted string started with ``'''`` 

208 "string13": [ 

209 (r"'''", String, "#pop"), 

210 include("stringescapes"), 

211 (r"[^\\']+", String), 

212 (r'.', String), 

213 ], 

214 # Inside a triple quoted string started with ``"""`` 

215 "string23": [ 

216 (r'"""', String, "#pop"), 

217 include("stringescapes"), 

218 (r'[^\\"]+', String), 

219 (r'.', String), 

220 ], 

221 # Inside a single quoted string started with ``'`` 

222 "string1": [ 

223 (r"'", String, "#pop"), 

224 include("stringescapes"), 

225 (r"[^\\']+", String), 

226 (r'.', String), 

227 ], 

228 # Inside a single quoted string started with ``"`` 

229 "string2": [ 

230 (r'"', String, "#pop"), 

231 include("stringescapes"), 

232 (r'[^\\"]+', String), 

233 (r'.', String), 

234 ], 

235 } 

236 

237class HTMLUL4Lexer(DelegatingLexer): 

238 """ 

239 Lexer for UL4 embedded in HTML. 

240 """ 

241 

242 name = 'HTML+UL4' 

243 aliases = ['html+ul4'] 

244 filenames = ['*.htmlul4'] 

245 url = 'https://python.livinglogic.de/UL4.html' 

246 version_added = '' 

247 

248 def __init__(self, **options): 

249 super().__init__(HtmlLexer, UL4Lexer, **options) 

250 

251 

252class XMLUL4Lexer(DelegatingLexer): 

253 """ 

254 Lexer for UL4 embedded in XML. 

255 """ 

256 

257 name = 'XML+UL4' 

258 aliases = ['xml+ul4'] 

259 filenames = ['*.xmlul4'] 

260 url = 'https://python.livinglogic.de/UL4.html' 

261 version_added = '' 

262 

263 def __init__(self, **options): 

264 super().__init__(XmlLexer, UL4Lexer, **options) 

265 

266 

267class CSSUL4Lexer(DelegatingLexer): 

268 """ 

269 Lexer for UL4 embedded in CSS. 

270 """ 

271 

272 name = 'CSS+UL4' 

273 aliases = ['css+ul4'] 

274 filenames = ['*.cssul4'] 

275 url = 'https://python.livinglogic.de/UL4.html' 

276 version_added = '' 

277 

278 def __init__(self, **options): 

279 super().__init__(CssLexer, UL4Lexer, **options) 

280 

281 

282class JavascriptUL4Lexer(DelegatingLexer): 

283 """ 

284 Lexer for UL4 embedded in Javascript. 

285 """ 

286 

287 name = 'Javascript+UL4' 

288 aliases = ['js+ul4'] 

289 filenames = ['*.jsul4'] 

290 url = 'https://python.livinglogic.de/UL4.html' 

291 version_added = '' 

292 

293 def __init__(self, **options): 

294 super().__init__(JavascriptLexer, UL4Lexer, **options) 

295 

296 

297class PythonUL4Lexer(DelegatingLexer): 

298 """ 

299 Lexer for UL4 embedded in Python. 

300 """ 

301 

302 name = 'Python+UL4' 

303 aliases = ['py+ul4'] 

304 filenames = ['*.pyul4'] 

305 url = 'https://python.livinglogic.de/UL4.html' 

306 version_added = '' 

307 

308 def __init__(self, **options): 

309 super().__init__(PythonLexer, UL4Lexer, **options)