Coverage for sources/ictr/standard/presentations.py: 75%
38 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-26 12:43 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-26 12:43 +0000
1# vim: set filetype=python fileencoding=utf-8:
2# -*- coding: utf-8 -*-
4#============================================================================#
5# #
6# Licensed under the Apache License, Version 2.0 (the "License"); #
7# you may not use this file except in compliance with the License. #
8# You may obtain a copy of the License at #
9# #
10# http://www.apache.org/licenses/LICENSE-2.0 #
11# #
12# Unless required by applicable law or agreed to in writing, software #
13# distributed under the License is distributed on an "AS IS" BASIS, #
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15# See the License for the specific language governing permissions and #
16# limitations under the License. #
17# #
18#============================================================================#
21''' Standard textual presentations. '''
24from . import __
25from . import linearizers as _linearizers
26from . import renderables as _renderables
29@__.typx.runtime_checkable
30class Presentation(
31 __.immut.DataclassProtocol, __.typx.Protocol,
32 class_mutables = __.PROTOCOL_RTC_MUTABLES,
33):
34 ''' Abstract base for presentations.
36 Detects and invokes renderables with configuration.
37 '''
39 @__.abc.abstractmethod
40 def is_renderable( self, entity: object ) -> bool:
41 ''' Does object support this presentation mode? '''
42 raise NotImplementedError
44 def linearize(
45 self, auxdata: _linearizers.LinearizerState, entity: object
46 ) -> tuple[ str, ... ]:
47 ''' Produces contiguous lines of text to render. '''
48 return tuple( self.render( auxdata, entity ).split( '\n' ) )
50 @__.abc.abstractmethod
51 def render(
52 self, auxdata: _linearizers.LinearizerState, entity: object
53 ) -> str:
54 ''' Renders object via its protocol implementation. '''
55 raise NotImplementedError
58class PlaintextPresentation( Presentation ):
59 ''' Default presentation via standard linearization. '''
61 def is_renderable( self, entity: object ) -> bool: return True 61 ↛ exitline 61 didn't return from function 'is_renderable' because the return on line 61 wasn't executed
63 def linearize(
64 self, auxdata: _linearizers.LinearizerState, entity: object
65 ) -> tuple[ str, ... ]:
66 from .linearizers import linearize_omni
67 # if isinstance( entity, PlaintextRenderable ):
68 # text = entity.render_as_plaintext( )
69 # return tuple( text.split( '\n' ) )
70 return linearize_omni( auxdata, entity, auxdata.columns_max )
72 def render(
73 self, auxdata: _linearizers.LinearizerState, entity: object
74 ) -> str:
75 return '\n'.join( self.linearize( auxdata, entity ) )
78_JSON_RENDERABLES = (
79 _renderables.JsonRenderable,
80 _renderables.JsonRenderableDataclass )
81class JsonPresentation( Presentation ):
82 ''' JSON presentation with configuration. '''
84 compact: bool = False
85 indent: int = 2
87 def is_renderable( self, entity: object ) -> bool:
88 return isinstance( entity, _JSON_RENDERABLES )
90 def render(
91 self, auxdata: _linearizers.LinearizerState, entity: object
92 ) -> str:
93 if isinstance( entity, _JSON_RENDERABLES ): 93 ↛ 96line 93 didn't jump to line 96 because the condition on line 93 was always true
94 return entity.render_as_json(
95 auxdata, compact = self.compact, indent = self.indent )
96 raise NotImplementedError # TODO: Better error.
99_MARKDOWN_RENDERABLES = (
100 _renderables.MarkdownRenderable,
101 _renderables.MarkdownRenderableDataclass )
102class MarkdownPresentation( Presentation ):
104 def is_renderable( self, entity: object ) -> bool:
105 return isinstance( entity, _MARKDOWN_RENDERABLES )
107 def render(
108 self, auxdata: _linearizers.LinearizerState, entity: object
109 ) -> str:
110 if isinstance( entity, _MARKDOWN_RENDERABLES ): 110 ↛ 112line 110 didn't jump to line 112 because the condition on line 110 was always true
111 return entity.render_as_markdown( auxdata )
112 raise NotImplementedError # TODO: Better error.