comparison mercurial/templater.py @ 24586:90e3f5d22dad

templater: add consistent docstrings to functions The content of "hg help templating" is largely derived from docstrings on functions providing functionality. Template functions are the long holdout. Prepare for generating them dynamically by defining docstrings for all template functions. There are numerous ways these docs could be improved. Right now, the help output simply shows function names and arguments. So literally any accurate data is better than what is there now.
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 01 Apr 2015 20:19:43 -0700
parents 696ab1a24ae0
children d80819f67d59
comparison
equal deleted inserted replaced
24585:e191d5d8d515 24586:90e3f5d22dad
217 f = context._filters[n] 217 f = context._filters[n]
218 return (runfilter, (args[0][0], args[0][1], f)) 218 return (runfilter, (args[0][0], args[0][1], f))
219 raise error.ParseError(_("unknown function '%s'") % n) 219 raise error.ParseError(_("unknown function '%s'") % n)
220 220
221 def date(context, mapping, args): 221 def date(context, mapping, args):
222 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
223 strings."""
222 if not (1 <= len(args) <= 2): 224 if not (1 <= len(args) <= 2):
223 # i18n: "date" is a keyword 225 # i18n: "date" is a keyword
224 raise error.ParseError(_("date expects one or two arguments")) 226 raise error.ParseError(_("date expects one or two arguments"))
225 227
226 date = args[0][0](context, mapping, args[0][1]) 228 date = args[0][0](context, mapping, args[0][1])
228 fmt = stringify(args[1][0](context, mapping, args[1][1])) 230 fmt = stringify(args[1][0](context, mapping, args[1][1]))
229 return util.datestr(date, fmt) 231 return util.datestr(date, fmt)
230 return util.datestr(date) 232 return util.datestr(date)
231 233
232 def diff(context, mapping, args): 234 def diff(context, mapping, args):
235 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
236 specifying files to include or exclude."""
233 if len(args) > 2: 237 if len(args) > 2:
234 # i18n: "diff" is a keyword 238 # i18n: "diff" is a keyword
235 raise error.ParseError(_("diff expects one, two or no arguments")) 239 raise error.ParseError(_("diff expects one, two or no arguments"))
236 240
237 def getpatterns(i): 241 def getpatterns(i):
245 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1))) 249 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
246 250
247 return ''.join(chunks) 251 return ''.join(chunks)
248 252
249 def fill(context, mapping, args): 253 def fill(context, mapping, args):
254 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
255 paragraphs with optional indentation. See the "fill" filter."""
250 if not (1 <= len(args) <= 4): 256 if not (1 <= len(args) <= 4):
251 # i18n: "fill" is a keyword 257 # i18n: "fill" is a keyword
252 raise error.ParseError(_("fill expects one to four arguments")) 258 raise error.ParseError(_("fill expects one to four arguments"))
253 259
254 text = stringify(args[0][0](context, mapping, args[0][1])) 260 text = stringify(args[0][0](context, mapping, args[0][1]))
268 pass 274 pass
269 275
270 return templatefilters.fill(text, width, initindent, hangindent) 276 return templatefilters.fill(text, width, initindent, hangindent)
271 277
272 def pad(context, mapping, args): 278 def pad(context, mapping, args):
273 """usage: pad(text, width, fillchar=' ', right=False) 279 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
274 """ 280 fill character."""
275 if not (2 <= len(args) <= 4): 281 if not (2 <= len(args) <= 4):
276 # i18n: "pad" is a keyword 282 # i18n: "pad" is a keyword
277 raise error.ParseError(_("pad() expects two to four arguments")) 283 raise error.ParseError(_("pad() expects two to four arguments"))
278 284
279 width = int(args[1][1]) 285 width = int(args[1][1])
294 return text.rjust(width, fillchar) 300 return text.rjust(width, fillchar)
295 else: 301 else:
296 return text.ljust(width, fillchar) 302 return text.ljust(width, fillchar)
297 303
298 def get(context, mapping, args): 304 def get(context, mapping, args):
305 """:get(dict, key): Get an attribute/key from an object. Some keywords
306 are complex types. This function allows you to obtain the value of an
307 attribute on these type."""
299 if len(args) != 2: 308 if len(args) != 2:
300 # i18n: "get" is a keyword 309 # i18n: "get" is a keyword
301 raise error.ParseError(_("get() expects two arguments")) 310 raise error.ParseError(_("get() expects two arguments"))
302 311
303 dictarg = args[0][0](context, mapping, args[0][1]) 312 dictarg = args[0][0](context, mapping, args[0][1])
315 compiletemplate(t, context, strtoken='rawstring')) 324 compiletemplate(t, context, strtoken='rawstring'))
316 else: 325 else:
317 yield t 326 yield t
318 327
319 def if_(context, mapping, args): 328 def if_(context, mapping, args):
329 """:if(expr, then[, else]): Conditionally execute based on the result of
330 an expression."""
320 if not (2 <= len(args) <= 3): 331 if not (2 <= len(args) <= 3):
321 # i18n: "if" is a keyword 332 # i18n: "if" is a keyword
322 raise error.ParseError(_("if expects two or three arguments")) 333 raise error.ParseError(_("if expects two or three arguments"))
323 334
324 test = stringify(args[0][0](context, mapping, args[0][1])) 335 test = stringify(args[0][0](context, mapping, args[0][1]))
326 yield _evalifliteral(args[1], context, mapping) 337 yield _evalifliteral(args[1], context, mapping)
327 elif len(args) == 3: 338 elif len(args) == 3:
328 yield _evalifliteral(args[2], context, mapping) 339 yield _evalifliteral(args[2], context, mapping)
329 340
330 def ifcontains(context, mapping, args): 341 def ifcontains(context, mapping, args):
342 """:ifcontains(search, thing, then[, else]): Conditionally execute based
343 on whether the item "search" is in "thing"."""
331 if not (3 <= len(args) <= 4): 344 if not (3 <= len(args) <= 4):
332 # i18n: "ifcontains" is a keyword 345 # i18n: "ifcontains" is a keyword
333 raise error.ParseError(_("ifcontains expects three or four arguments")) 346 raise error.ParseError(_("ifcontains expects three or four arguments"))
334 347
335 item = stringify(args[0][0](context, mapping, args[0][1])) 348 item = stringify(args[0][0](context, mapping, args[0][1]))
339 yield _evalifliteral(args[2], context, mapping) 352 yield _evalifliteral(args[2], context, mapping)
340 elif len(args) == 4: 353 elif len(args) == 4:
341 yield _evalifliteral(args[3], context, mapping) 354 yield _evalifliteral(args[3], context, mapping)
342 355
343 def ifeq(context, mapping, args): 356 def ifeq(context, mapping, args):
357 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
358 whether 2 items are equivalent."""
344 if not (3 <= len(args) <= 4): 359 if not (3 <= len(args) <= 4):
345 # i18n: "ifeq" is a keyword 360 # i18n: "ifeq" is a keyword
346 raise error.ParseError(_("ifeq expects three or four arguments")) 361 raise error.ParseError(_("ifeq expects three or four arguments"))
347 362
348 test = stringify(args[0][0](context, mapping, args[0][1])) 363 test = stringify(args[0][0](context, mapping, args[0][1]))
351 yield _evalifliteral(args[2], context, mapping) 366 yield _evalifliteral(args[2], context, mapping)
352 elif len(args) == 4: 367 elif len(args) == 4:
353 yield _evalifliteral(args[3], context, mapping) 368 yield _evalifliteral(args[3], context, mapping)
354 369
355 def join(context, mapping, args): 370 def join(context, mapping, args):
371 """:join(list, sep): Join items in a list with a delimiter."""
356 if not (1 <= len(args) <= 2): 372 if not (1 <= len(args) <= 2):
357 # i18n: "join" is a keyword 373 # i18n: "join" is a keyword
358 raise error.ParseError(_("join expects one or two arguments")) 374 raise error.ParseError(_("join expects one or two arguments"))
359 375
360 joinset = args[0][0](context, mapping, args[0][1]) 376 joinset = args[0][0](context, mapping, args[0][1])
373 else: 389 else:
374 yield joiner 390 yield joiner
375 yield x 391 yield x
376 392
377 def label(context, mapping, args): 393 def label(context, mapping, args):
394 """:label(label, expr): Apply a label to generated content. Content with
395 a label applied can result in additional post-processing, such as
396 automatic colorization."""
378 if len(args) != 2: 397 if len(args) != 2:
379 # i18n: "label" is a keyword 398 # i18n: "label" is a keyword
380 raise error.ParseError(_("label expects two arguments")) 399 raise error.ParseError(_("label expects two arguments"))
381 400
382 # ignore args[0] (the label string) since this is supposed to be a a no-op 401 # ignore args[0] (the label string) since this is supposed to be a a no-op
383 yield _evalifliteral(args[1], context, mapping) 402 yield _evalifliteral(args[1], context, mapping)
384 403
385 def revset(context, mapping, args): 404 def revset(context, mapping, args):
386 """usage: revset(query[, formatargs...]) 405 """:revset(query[, formatargs...]): Execute a revision set query. See
387 """ 406 :hg:`help revset`."""
388 if not len(args) > 0: 407 if not len(args) > 0:
389 # i18n: "revset" is a keyword 408 # i18n: "revset" is a keyword
390 raise error.ParseError(_("revset expects one or more arguments")) 409 raise error.ParseError(_("revset expects one or more arguments"))
391 410
392 raw = args[0][1] 411 raw = args[0][1]
411 revsetcache[raw] = revs 430 revsetcache[raw] = revs
412 431
413 return templatekw.showlist("revision", revs, **mapping) 432 return templatekw.showlist("revision", revs, **mapping)
414 433
415 def rstdoc(context, mapping, args): 434 def rstdoc(context, mapping, args):
435 """:rstdoc(text, style): Format ReStructuredText."""
416 if len(args) != 2: 436 if len(args) != 2:
417 # i18n: "rstdoc" is a keyword 437 # i18n: "rstdoc" is a keyword
418 raise error.ParseError(_("rstdoc expects two arguments")) 438 raise error.ParseError(_("rstdoc expects two arguments"))
419 439
420 text = stringify(args[0][0](context, mapping, args[0][1])) 440 text = stringify(args[0][0](context, mapping, args[0][1]))
421 style = stringify(args[1][0](context, mapping, args[1][1])) 441 style = stringify(args[1][0](context, mapping, args[1][1]))
422 442
423 return minirst.format(text, style=style, keep=['verbose']) 443 return minirst.format(text, style=style, keep=['verbose'])
424 444
425 def shortest(context, mapping, args): 445 def shortest(context, mapping, args):
426 """usage: shortest(node, minlength=4) 446 """:shortest(node, minlength=4): Obtain the shortest representation of
427 """ 447 a node."""
428 if not (1 <= len(args) <= 2): 448 if not (1 <= len(args) <= 2):
429 # i18n: "shortest" is a keyword 449 # i18n: "shortest" is a keyword
430 raise error.ParseError(_("shortest() expects one or two arguments")) 450 raise error.ParseError(_("shortest() expects one or two arguments"))
431 451
432 node = stringify(args[0][0](context, mapping, args[0][1])) 452 node = stringify(args[0][0](context, mapping, args[0][1]))
473 length += 1 493 length += 1
474 if len(shortest) <= length: 494 if len(shortest) <= length:
475 return shortest 495 return shortest
476 496
477 def strip(context, mapping, args): 497 def strip(context, mapping, args):
498 """:strip(text[, chars]): Strip characters from a string."""
478 if not (1 <= len(args) <= 2): 499 if not (1 <= len(args) <= 2):
479 # i18n: "strip" is a keyword 500 # i18n: "strip" is a keyword
480 raise error.ParseError(_("strip expects one or two arguments")) 501 raise error.ParseError(_("strip expects one or two arguments"))
481 502
482 text = stringify(args[0][0](context, mapping, args[0][1])) 503 text = stringify(args[0][0](context, mapping, args[0][1]))
484 chars = stringify(args[1][0](context, mapping, args[1][1])) 505 chars = stringify(args[1][0](context, mapping, args[1][1]))
485 return text.strip(chars) 506 return text.strip(chars)
486 return text.strip() 507 return text.strip()
487 508
488 def sub(context, mapping, args): 509 def sub(context, mapping, args):
510 """:sub(pattern, replacement, expression): Perform text substitution
511 using regular expressions."""
489 if len(args) != 3: 512 if len(args) != 3:
490 # i18n: "sub" is a keyword 513 # i18n: "sub" is a keyword
491 raise error.ParseError(_("sub expects three arguments")) 514 raise error.ParseError(_("sub expects three arguments"))
492 515
493 pat = stringify(args[0][0](context, mapping, args[0][1])) 516 pat = stringify(args[0][0](context, mapping, args[0][1]))
494 rpl = stringify(args[1][0](context, mapping, args[1][1])) 517 rpl = stringify(args[1][0](context, mapping, args[1][1]))
495 src = stringify(_evalifliteral(args[2], context, mapping)) 518 src = stringify(_evalifliteral(args[2], context, mapping))
496 yield re.sub(pat, rpl, src) 519 yield re.sub(pat, rpl, src)
497 520
498 def startswith(context, mapping, args): 521 def startswith(context, mapping, args):
522 """:startswith(pattern, text): Returns the value from the "text" argument
523 if it begins with the content from the "pattern" argument."""
499 if len(args) != 2: 524 if len(args) != 2:
500 # i18n: "startswith" is a keyword 525 # i18n: "startswith" is a keyword
501 raise error.ParseError(_("startswith expects two arguments")) 526 raise error.ParseError(_("startswith expects two arguments"))
502 527
503 patn = stringify(args[0][0](context, mapping, args[0][1])) 528 patn = stringify(args[0][0](context, mapping, args[0][1]))
506 return text 531 return text
507 return '' 532 return ''
508 533
509 534
510 def word(context, mapping, args): 535 def word(context, mapping, args):
511 """return nth word from a string""" 536 """:word(number, text[, separator]): Return the nth word from a string."""
512 if not (2 <= len(args) <= 3): 537 if not (2 <= len(args) <= 3):
513 # i18n: "word" is a keyword 538 # i18n: "word" is a keyword
514 raise error.ParseError(_("word expects two or three arguments, got %d") 539 raise error.ParseError(_("word expects two or three arguments, got %d")
515 % len(args)) 540 % len(args))
516 541