473 |
473 |
474 return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f) |
474 return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f) |
475 |
475 |
476 |
476 |
477 class templateformatter(baseformatter): |
477 class templateformatter(baseformatter): |
478 def __init__(self, ui, out, topic, opts, spec): |
478 def __init__(self, ui, out, topic, opts, spec, overridetemplates=None): |
479 baseformatter.__init__(self, ui, topic, opts, _templateconverter) |
479 baseformatter.__init__(self, ui, topic, opts, _templateconverter) |
480 self._out = out |
480 self._out = out |
481 self._tref = spec.ref |
481 self._tref = spec.ref |
482 self._t = loadtemplater( |
482 self._t = loadtemplater( |
483 ui, |
483 ui, |
484 spec, |
484 spec, |
485 defaults=templatekw.keywords, |
485 defaults=templatekw.keywords, |
486 resources=templateresources(ui), |
486 resources=templateresources(ui), |
487 cache=templatekw.defaulttempl, |
487 cache=templatekw.defaulttempl, |
488 ) |
488 ) |
|
489 if overridetemplates: |
|
490 self._t.cache.update(overridetemplates) |
489 self._parts = templatepartsmap( |
491 self._parts = templatepartsmap( |
490 spec, self._t, [b'docheader', b'docfooter', b'separator'] |
492 spec, self._t, [b'docheader', b'docfooter', b'separator'] |
491 ) |
493 ) |
492 self._counter = itertools.count() |
494 self._counter = itertools.count() |
493 self._renderitem(b'docheader', {}) |
495 self._renderitem(b'docheader', {}) |
553 return templatespec(b'', tmpl, None) |
556 return templatespec(b'', tmpl, None) |
554 |
557 |
555 # a reference to built-in (formatter) template |
558 # a reference to built-in (formatter) template |
556 if tmpl in {b'cbor', b'json', b'pickle', b'debug'}: |
559 if tmpl in {b'cbor', b'json', b'pickle', b'debug'}: |
557 return templatespec(tmpl, None, None) |
560 return templatespec(tmpl, None, None) |
|
561 |
|
562 # a function-style reference to built-in template |
|
563 func, fsep, ftail = tmpl.partition(b'(') |
|
564 if func in {b'cbor', b'json'} and fsep and ftail.endswith(b')'): |
|
565 templater.parseexpr(tmpl) # make sure syntax errors are confined |
|
566 return templatespec(func, None, None, refargs=ftail[:-1]) |
558 |
567 |
559 # perhaps a stock style? |
568 # perhaps a stock style? |
560 if not os.path.split(tmpl)[0]: |
569 if not os.path.split(tmpl)[0]: |
561 mapname = templater.templatepath( |
570 mapname = templater.templatepath( |
562 b'map-cmdline.' + tmpl |
571 b'map-cmdline.' + tmpl |
717 b'ctx': _loadctx, |
726 b'ctx': _loadctx, |
718 b'fctx': _loadfctx, |
727 b'fctx': _loadfctx, |
719 } |
728 } |
720 |
729 |
721 |
730 |
|
731 def _internaltemplateformatter( |
|
732 ui, |
|
733 out, |
|
734 topic, |
|
735 opts, |
|
736 spec, |
|
737 tmpl, |
|
738 docheader=b'', |
|
739 docfooter=b'', |
|
740 separator=b'', |
|
741 ): |
|
742 """Build template formatter that handles customizable built-in templates |
|
743 such as -Tjson(...)""" |
|
744 templates = {spec.ref: tmpl} |
|
745 if docheader: |
|
746 templates[b'%s:docheader' % spec.ref] = docheader |
|
747 if docfooter: |
|
748 templates[b'%s:docfooter' % spec.ref] = docfooter |
|
749 if separator: |
|
750 templates[b'%s:separator' % spec.ref] = separator |
|
751 return templateformatter( |
|
752 ui, out, topic, opts, spec, overridetemplates=templates |
|
753 ) |
|
754 |
|
755 |
722 def formatter(ui, out, topic, opts): |
756 def formatter(ui, out, topic, opts): |
723 spec = lookuptemplate(ui, topic, opts.get(b'template', b'')) |
757 spec = lookuptemplate(ui, topic, opts.get(b'template', b'')) |
724 if spec.ref == b"cbor": |
758 if spec.ref == b"cbor" and spec.refargs is not None: |
|
759 return _internaltemplateformatter( |
|
760 ui, |
|
761 out, |
|
762 topic, |
|
763 opts, |
|
764 spec, |
|
765 tmpl=b'{dict(%s)|cbor}' % spec.refargs, |
|
766 docheader=cborutil.BEGIN_INDEFINITE_ARRAY, |
|
767 docfooter=cborutil.BREAK, |
|
768 ) |
|
769 elif spec.ref == b"cbor": |
725 return cborformatter(ui, out, topic, opts) |
770 return cborformatter(ui, out, topic, opts) |
|
771 elif spec.ref == b"json" and spec.refargs is not None: |
|
772 return _internaltemplateformatter( |
|
773 ui, |
|
774 out, |
|
775 topic, |
|
776 opts, |
|
777 spec, |
|
778 tmpl=b'{dict(%s)|json}' % spec.refargs, |
|
779 docheader=b'[\n ', |
|
780 docfooter=b'\n]\n', |
|
781 separator=b',\n ', |
|
782 ) |
726 elif spec.ref == b"json": |
783 elif spec.ref == b"json": |
727 return jsonformatter(ui, out, topic, opts) |
784 return jsonformatter(ui, out, topic, opts) |
728 elif spec.ref == b"pickle": |
785 elif spec.ref == b"pickle": |
|
786 assert spec.refargs is None, r'function-style not supported' |
729 return pickleformatter(ui, out, topic, opts) |
787 return pickleformatter(ui, out, topic, opts) |
730 elif spec.ref == b"debug": |
788 elif spec.ref == b"debug": |
|
789 assert spec.refargs is None, r'function-style not supported' |
731 return debugformatter(ui, out, topic, opts) |
790 return debugformatter(ui, out, topic, opts) |
732 elif spec.ref or spec.tmpl or spec.mapfile: |
791 elif spec.ref or spec.tmpl or spec.mapfile: |
|
792 assert spec.refargs is None, r'function-style not supported' |
733 return templateformatter(ui, out, topic, opts, spec) |
793 return templateformatter(ui, out, topic, opts, spec) |
734 # developer config: ui.formatdebug |
794 # developer config: ui.formatdebug |
735 elif ui.configbool(b'ui', b'formatdebug'): |
795 elif ui.configbool(b'ui', b'formatdebug'): |
736 return debugformatter(ui, out, topic, opts) |
796 return debugformatter(ui, out, topic, opts) |
737 # deprecated config: ui.formatjson |
797 # deprecated config: ui.formatjson |