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

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

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#============================================================================# 

19 

20 

21''' Standard textual presentations. ''' 

22 

23 

24from . import __ 

25from . import linearizers as _linearizers 

26from . import renderables as _renderables 

27 

28 

29@__.typx.runtime_checkable 

30class Presentation( 

31 __.immut.DataclassProtocol, __.typx.Protocol, 

32 class_mutables = __.PROTOCOL_RTC_MUTABLES, 

33): 

34 ''' Abstract base for presentations. 

35 

36 Detects and invokes renderables with configuration. 

37 ''' 

38 

39 @__.abc.abstractmethod 

40 def is_renderable( self, entity: object ) -> bool: 

41 ''' Does object support this presentation mode? ''' 

42 raise NotImplementedError 

43 

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' ) ) 

49 

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 

56 

57 

58class PlaintextPresentation( Presentation ): 

59 ''' Default presentation via standard linearization. ''' 

60 

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

62 

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 ) 

71 

72 def render( 

73 self, auxdata: _linearizers.LinearizerState, entity: object 

74 ) -> str: 

75 return '\n'.join( self.linearize( auxdata, entity ) ) 

76 

77 

78_JSON_RENDERABLES = ( 

79 _renderables.JsonRenderable, 

80 _renderables.JsonRenderableDataclass ) 

81class JsonPresentation( Presentation ): 

82 ''' JSON presentation with configuration. ''' 

83 

84 compact: bool = False 

85 indent: int = 2 

86 

87 def is_renderable( self, entity: object ) -> bool: 

88 return isinstance( entity, _JSON_RENDERABLES ) 

89 

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. 

97 

98 

99_MARKDOWN_RENDERABLES = ( 

100 _renderables.MarkdownRenderable, 

101 _renderables.MarkdownRenderableDataclass ) 

102class MarkdownPresentation( Presentation ): 

103 

104 def is_renderable( self, entity: object ) -> bool: 

105 return isinstance( entity, _MARKDOWN_RENDERABLES ) 

106 

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.