Coverage for src/pycse/orgmode.py: 0.00%

121 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-23 16:23 -0400

1"""Provides classes to convert python data into org markup.""" 

2 

3import IPython 

4import tabulate 

5 

6 

7class Heading: 

8 """An orgmode headline.""" 

9 

10 def __init__(self, title, level=1, tags=(), properties=None): 

11 """Initialize a Heading.""" 

12 self.title = title 

13 self.level = level 

14 self.tags = tags 

15 self.properties = properties 

16 

17 def _repr_org(self): 

18 """Provide an org representation.""" 

19 s = "*" * self.level + " " + self.title 

20 if self.tags: 

21 s += f" :{':'.join(self.tags)}:" 

22 if self.properties: 

23 s += "\n:PROPERTIES:\n" 

24 for key in self.properties: 

25 s += f":{key}: {self.properties[key]}\n" 

26 s += ":END:" 

27 return s + "\n" 

28 

29 def _repr_html(self): 

30 """HTML representation of a Heading.""" 

31 return f"<h{self.level}>{self.title}</h{self.level}>" 

32 

33 def _repr_mimebundle_(self, include, exclude, **kwargs): 

34 """Mimebundle representation of a Heading. 

35 

36 repr_mimebundle should accept include, exclude and **kwargs. 

37 """ 

38 data = {"text/html": self._repr_html(), "text/org": self._repr_org()} 

39 if include: 

40 data = {k: v for (k, v) in data.items() if k in include} 

41 if exclude: 

42 data = {k: v for (k, v) in data.items() if k not in exclude} 

43 return data 

44 

45 

46class Keyword: 

47 """Keyword(key, value) -> #+key: value.""" 

48 

49 def __init__(self, key, value): 

50 """Initialize a Keyword.""" 

51 self.key = key 

52 self.value = value 

53 

54 def _repr_org(self): 

55 """Provide org representation.""" 

56 return f"#+{self.key}: {self.value}" + "\n" 

57 

58 def _repr_mimebundle_(self, include, exclude, **kwargs): 

59 """Provide a mimebundle representation. 

60 

61 repr_mimebundle should accept include, exclude and **kwargs 

62 """ 

63 data = {"text/org": self._repr_org()} 

64 if include: 

65 data = {k: v for (k, v) in data.items() if k in include} 

66 if exclude: 

67 data = {k: v for (k, v) in data.items() if k not in exclude} 

68 return data 

69 

70 

71class Comment: 

72 """Comment(text) -> # text.""" 

73 

74 def __init__(self, text): 

75 """Initialize a comment.""" 

76 self.text = text 

77 

78 def _repr_org(self): 

79 """Provide an org representation.""" 

80 return f"# {self.text}" + "\n" 

81 

82 def _repr_mimebundle_(self, include, exclude, **kwargs): 

83 """Provide a mimebundle representation. 

84 

85 repr_mimebundle should accept include, exclude and **kwargs 

86 """ 

87 data = {"text/org": self._repr_org()} 

88 if include: 

89 data = {k: v for (k, v) in data.items() if k in include} 

90 if exclude: 

91 data = {k: v for (k, v) in data.items() if k not in exclude} 

92 return data 

93 

94 

95class Org: 

96 """Org(text) -> text.""" 

97 

98 def __init__(self, text): 

99 """Initialize an Org object.""" 

100 self.text = text 

101 

102 def _repr_org(self): 

103 """Provide an org representation.""" 

104 return self.text + "\n" 

105 

106 def _repr_mimebundle_(self, include, exclude, **kwargs): 

107 """Provide a mimebundle representation. 

108 

109 repr_mimebundle should accept include, exclude and **kwargs 

110 """ 

111 data = {"text/org": self._repr_org()} 

112 if include: 

113 data = {k: v for (k, v) in data.items() if k in include} 

114 if exclude: 

115 data = {k: v for (k, v) in data.items() if k not in exclude} 

116 return data 

117 

118 

119class Figure: 

120 """A Figure class for org. 

121 

122 It combines a filename, caption, name and attributes. 

123 """ 

124 

125 def __init__(self, fname, caption=None, name=None, attributes=()): 

126 """Initialize a figure.""" 

127 self.fname = fname 

128 self.caption = caption 

129 self.name = name 

130 self.attributes = attributes 

131 

132 def _repr_org(self): 

133 s = [] 

134 for backend, attrs in self.attributes: 

135 s += [f"#+attr_{backend}: {attrs}"] 

136 

137 if self.name: 

138 s += [f"#+name: {self.name}"] 

139 

140 if self.caption: 

141 s += [f"#+caption: {self.caption}"] 

142 

143 s += [f"[[{self.fname}]]"] 

144 

145 return "\n".join(s) + "\n" 

146 

147 def _repr_mimebundle_(self, include, exclude, **kwargs): 

148 """Provide a mimebundle representation. 

149 

150 repr_mimebundle should accept include, exclude and **kwargs. 

151 """ 

152 data = {"text/org": self._repr_org()} 

153 if include: 

154 data = {k: v for (k, v) in data.items() if k in include} 

155 if exclude: 

156 data = {k: v for (k, v) in data.items() if k not in exclude} 

157 return data 

158 

159 

160class Table: 

161 """A Table object for org.""" 

162 

163 def __init__(self, data, headers=None, caption=None, name=None, attributes=()): 

164 """Initialize a table.""" 

165 self.data = data 

166 self.headers = headers 

167 self.caption = caption 

168 self.name = name 

169 self.attributes = attributes 

170 

171 def _repr_org(self): 

172 """Provide an org representation.""" 

173 s = [] 

174 for backend, attributes in self.attributes: 

175 s += [f"#+attr_{backend}: {attributes}"] 

176 

177 if self.name: 

178 s += [f"#+name: {self.name}"] 

179 

180 if self.caption: 

181 s += [f"#+caption: {self.caption}"] 

182 

183 s += [tabulate.tabulate(self.data, self.headers, tablefmt="orgtbl")] 

184 

185 return "\n".join(s) 

186 

187 def _repr_mimebundle_(self, include, exclude, **kwargs): 

188 """Provide a mimebundle representation. 

189 

190 repr_mimebundle should accept include, exclude and **kwargs 

191 """ 

192 data = {"text/org": self._repr_org()} 

193 if include: 

194 data = {k: v for (k, v) in data.items() if k in include} 

195 if exclude: 

196 data = {k: v for (k, v) in data.items() if k not in exclude} 

197 return data 

198 

199 

200# * Rich displays for org-mode 

201 

202 

203class OrgFormatter(IPython.core.formatters.BaseFormatter): 

204 """A special formatter for org objects.""" 

205 

206 format_type = IPython.core.formatters.Unicode("text/org") 

207 print_method = IPython.core.formatters.ObjectName("_repr_org_") 

208 

209 

210try: 

211 ip = get_ipython() 

212 ip.display_formatter.formatters["text/org"] = OrgFormatter() 

213 ytv_f = ip.display_formatter.formatters["text/org"] 

214 ytv_f.for_type_by_name("IPython.lib.display", "YouTubeVideo", lambda V: f"{V.src}") 

215# get_ipython is not defined for tests I think. 

216except NameError: 

217 pass